更改元素 ID,但 jQuery 仍会触发调用旧 ID 的事件。为什么这行得通?

Change element ID, but jQuery still fires event calling old ID. Why does this work?

我创建了一个 fiddle 来尝试调试我遇到的问题,一旦我用 jQuery 重新排列 html 元素,这些元素上的悬停事件就不再起作用.

然而,我在这里遇到了这个有趣的情况:http://jsfiddle.net/4yv1trj4/

我有一个主要 div,当我将鼠标悬停在它上面时它会改变颜色。

$("#block").hover(function() {
     $(this).css("backgroundColor", "red");
}, function() {
    $(this).css("backgroundColor", "#888");        
});

如果单击该按钮,主要 div 的 ID 将更改为 block2:

$("#block").attr("id","block2");

但是当我将鼠标悬停在 #block2 上时 $("#block").hover() 仍然会触发。此外,#block2 上的所有悬停调用均无效。是否有 jQuery 工作原理的基本原理可以解释这一点?

当你这样做时:

$("#block").hover(function() {
    $(this).css("backgroundColor", "red");
}, function() {
    $(this).css("backgroundColor", "#888");        
});

您要告诉 jQuery 查找具有 block ID 的元素并将悬停事件绑定到它。完成此操作后,事件将保持绑定到该元素,无论之后其 ID 发生什么变化。

也就是说,除非你有一些代码 unbinds 当然可以。

如果您删除 jQuery 悬停侦听器并添加 CSS 悬停,它会按照您想要的方式工作:

#block:hover {
    background-color:red;
    width:300px;
    height:300px;
}

作为 lucasnadalutti 回答的扩展:值得注意的是,您可以将绑定添加到容器并产生您期望的结果:

示例:

$("body").on("mouseenter", "#block", function () {
    $(this).css("backgroundColor", "red");
}).on('mouseleave', "#block", function () {
    $(this).css("backgroundColor", "#888");
});

请注意 body 上的绑定,而不是实际元素。放在后兜的小窍门。

演示: jsFiddle


更新:

在评论部分,很明显需要警告 - 您应该绑定到页面上最近的元素。 body 在这里作为一个简单的例子。

虽然我认为这个解决方案很适合你,但在开始滥用该权力之前你应该阅读 Should all jquery events be bound to $(document)?

$("#block") 正在寻找特定的 DOM 对象。 .hover() 会将悬停事件绑定到 DOM 对象。 $("#block").attr("id","block2"); 将更改该 DOM 对象的属性 (id),但悬停事件仍与其绑定。