事件触发的jQuery问题

时间:2011-04-18 13:16:06

标签: jquery

$('.sss').click(function() {
  $("#a"+id).html("<textarea id=\"txt\" rows=\"8\" cols=\"75\">fddscx</textarea> <br />"+
                  "<input type=\"button\" id=\"xxx\" value=\"Do smth button\" class=\"submit_button\" />");
});

$('#xxx').click(function() {
    alert("button happened");
});

我点击了包含sss类的内容。然后会出现一个ID为xxx的按钮。当我点击它时为什么不给我一个警报?

谢谢。

2 个答案:

答案 0 :(得分:3)

它不起作用,因为您在元素是dom的一部分之前创建了处理程序。 您应该在容器元素上使用.delegate。 Delegate允许您处理当前和未来元素的事件。

您案例中的一个例子是

function clickHandler(){

     alert("button happened");

}

$('#someContainer').delegate('.sss', 'click' , clickHandler);

答案 1 :(得分:2)

这不起作用,因为您的按钮已动态添加到文档中,并且您将click事件添加到尚不存在的元素中。单击.sss元素后,它将存在。

您有两种方法可以解决您的问题:

解决方案解决方案:使用live() / .delegate()代替.click()

您可以使用.click()而不是使用.live()来将事件绑定到现有元素和未来元素(但不要将其视为银弹并开始在任何地方使用它)。这实际上将click事件绑定到document并检查是否在与选择器匹配的元素上触发了实际的click事件。这意味着live()(以及.delegate())功能可以更频繁地执行所有这些检查。所以明智地使用它:

$('#xxx').live("click", function() {
    alert("button happened");
})

最佳解决方案:即使在您创建按钮

后也要附加

最好和正确的方法当然是在创建元素后绑定事件。这就是.sss元素的点击事件:

$('.sss').click(function() {

    $("#a"+id).html("<textarea id=\"txt\" rows=\"8\" cols=\"75\">fddscx</textarea> <br />"+
                    "<input type=\"button\" id=\"xxx\" value=\"Do smth button\" class=\"submit_button\" />");
    $('#xxx').click(function() {
        alert("button happened");
    })
})

我建议你使用第二种解决方案。

让我们比较这些解决方案

活动登记

.click().live()都必须首先执行jQuery选择器然后将事件(.click()直接绑定到选定的元素.live()documement并保存jQuery无论是否存在具有该选择器的任何元素,都可以使用选择器。

.delegate()选择一个将绑定事件的元素。与.live()类似,它也保存了选择器。

执行速度

.click()在这里是明显的赢家,因为它将直接在元素上执行,而不会产生任何选择器匹配的开销。

.delegate().live()都有一些选择器匹配的开销。但更大的问题是想象用户点击整个文档(这是非常常见的,因为用户定期与点击进行交互)。在使用.live()时评估每次点击。并且根据.delegate()的容器选择,可以说同样如此。它们都执行的事件比实际应该执行的事件多得多。

当点击发生时,它会一直冒泡到其容器(不管是document还是与.delegate()相关联的其他容器。必须评估每次单击是否与目标元素匹配选择器。如果是这样,jQuery还会执行提供的事件处理程序以及.live().delegate()事件绑定。

判决

与评估用户点击文档中的某些内容(无论如何)的选择器时间相比,执行一次jQuery选择器仍然没那么糟糕。因此,我发现.live().delegate()事件注册类似,应尽可能避免。

尽可能使用直接事件绑定。这是最快的执行,通常比事件注册更频繁。