为什么第二次调用.html()会停止click()函数的工作?

时间:2014-12-10 14:37:54

标签: jquery dom

我问过一个有点相关的问题here。我有以下简单的HTML和jQuery代码

<html>
<body style="font-size:25px">

<div><p> CLICK TO TEST </p></div>

<script src="/js/jquery-1.11.1.min.js"></script>

<script>
$(function() {
    $("p").click(function() { console.log("P1 CLICKED!"); });

    var $div = $("div").detach();

    $("body").html($div);
    //$("body").html($div); // If I uncomment this the click event stops firing!!
});
</script>

</body>
</html>

在上面的代码中,如果我取消注释再次调用.html()的行,则click事件会停止触发,但我认为$div jQuery对象只会再次替换body内容不会丢失其点击事件。

如何解释?

2 个答案:

答案 0 :(得分:1)

您可以将事件监听器更改为

$(document).on("click", "p", function() {
  // whatever
});

我将触发每个p元素,无论它们是否在页面加载完成后添加。

答案 1 :(得分:1)

正如related question所述,无论您传递给html,这些行都会运行:

if ( elem ) {
    this.empty().append( value );
}

现在,了解.empty clear the data of the element非常重要。它表示存储在.data()内的所有内容,并删除每个事件以防止内存泄漏。

因此,第一次执行$("body").html($div);时,p不在身体内部,因为您.detach之前已经编过它。 .empty不影响p并保留其事件。但是如果你连续做了2次,那么在第一个.html.empty生效后,该元素会重新附加到身体上。它抹去了它的事件。

解决方案是使用事件委派,这很简单,不需要.detach任何事情:

$('body').on("click", "p", function() {
  //Your code
});