为什么AJAX请求创建的事件触发器必须在AJAX请求中?

时间:2012-08-09 14:02:26

标签: jquery ajax events

为什么这样做:

$.ajax(
{
    url: "/some/url.php",
    data: { s:"stuff" },
    success: function(result)
    {
        // Result being <button id="clickme">Click me!</button>
        $("#container").html(result); 

        // Event trigger *in* AJAX
        $("#clickme").on("click", function()
        {
           alert("Hai"); 
        });
    }
});

这不是:

$.ajax(
{
    url: "/some/url.php",
    data: { s:"stuff" },
    success: function(result)
    {
        // Result being <button id="clickme">Click me!</button>
        $("#container").html(result); 
    }
});

// Event trigger outside AJAX, for better overview, like event grouping, 
// shorter AJAX functions, etc
$("#clickme").on("click", function()
{
    alert("Hai"); 
});

使用jQuery v1.7.2

4 个答案:

答案 0 :(得分:7)

首先,on不使用具有该签名的委托。这意味着它直接将事件监听器附加到找到的元素。

其次,你的第二个代码是在做出ajax请求之前执行的,所以此时没有找到任何元素,代码也没有附加任何事件监听器。

如果您想使用on的委托,签名就像:

$(document).on( "click", "#clickme", function(){

});

document 应该最接近静态父元素 - 但它也适用于document(毕竟这是.live所做的)

document是可靠的,因为它始终存在。但是如果你有一个更接近静态的父元素,可以在DOM中找到,你可以宁愿委托给它。


不推荐document"body"等原因是因为它们会为页面上的所有type事件添加处理开销。

考虑$(document).on("mousemove", ".myElement", fn);

现在,只要鼠标在页面上移动,除非传播被较低级别的侦听器停止,否则jQuery必须处理整个传播路径 每次查看传播路径中的任何元素是否与给定的.myElement - 选择器匹配。

如果您改为添加$("#element").on("mousemove", ".myElement", fn);,则只会对发生的mousemove事件执行此处理 在页面的"#element"区域。

答案 1 :(得分:3)

尝试

$('body').on("click", "#clickme", function() {
    alert("Hai"); 
});

您的第二个代码段无法正常工作,因为当您附加处理程序时,元素#clickme尚不存在

答案 2 :(得分:0)

请改用:

$(document).on("click", "#clickme", function() { alert("Hai"); });

这应该有效。

答案 3 :(得分:0)

因为在第二种情况下,你试图设置点击处理程序的元素在pageLoad上不存在。

如果你像这样使用.on():

$("body").on("click", "#clickme", function()
{
    alert("Hi"); 
});

它可以工作,因为你将事件附加到body标签(在页面加载时存在),然后#clickme的选择仅在点击事件触发时解决。

但是比'body'(性能)更好的是你知道在页面加载中存在的DOM下面的一些容器。