我曾经在 AJAX 创建给定类时为给定类的每个元素分配一个单独的事件处理程序,如下所示:
$('#newId').on('click', function (e) {...
我已经更改为为适用于所有元素的类提供一个处理程序,如下所示:
$('#container').on('click', '.myClass', function (e) {...
我一直想知道当处理程序被触发时,这究竟是如何工作的,以及性能可能产生的影响。更具体地说,...
元素究竟如何找到类处理程序?这是否比每个元素有一个处理程序慢?该类是否真的只有一个事件处理程序,或者它是否以某种方式为类中的每个元素复制?
如评论中所述,每种方法都有优点和缺点。
当您有一个包含子元素的容器时,事件委派通常很好。想想一个带有编辑/删除按钮的大型无序列表。单击删除按钮时,您很可能会删除其父级 li。如果没有事件委托,您将负责解除绑定在这些元素上的任何事件处理程序的绑定。
事件委托使用 DOM 的事件冒泡属性。当 click 事件在 #container 的子级上触发时,该事件将在节点树中冒泡,在此过程中搜索事件的处理程序。然后测试事件目标,以查看它是否与选择器匹配。如果是这样,则调用绑定的单击处理程序。如果没有jQuery,这可能看起来像...
function myclass_click_handler() {
// an element with myClass has been called
}
document.getElementById('container').addEventListener('click', function(e) {
if (e.target.className.indexOf('myClass') > -1) {
myclass_click_handler();
}
});
事件委派的缺点之一是它不适用于所有事件。从性能的角度来看,它实际上可以提高性能,因为内存泄漏的可能性较小。
当基于类直接将回调分配给元素时,每个元素都将获得对回调函数的引用。如果需要删除任意数量的这些元素,则需要取消绑定这些元素的事件处理程序。当你使用 remove() 方法时,jQuery 通过删除绑定的事件处理程序来帮助解决这个问题。
希望这有帮助!