gpt4 book ai didi

javascript - 动态绑定(bind)事件处理程序的最有效方法

转载 作者:数据小太阳 更新时间:2023-10-29 04:20:38 25 4
gpt4 key购买 nike

问题: 我需要动态地将任意数量的事件处理程序绑定(bind)到任意数量的元素(DOM 节点、windowdocument)运行时,我需要能够在页面的生命周期内为动态创建(或销毁)的节点更新事件绑定(bind)。我可以看到三个选项来解决这个问题:

I) window
事件委托(delegate)II) 每个节点直接绑定(bind)事件
III) 共同祖先的事件委托(delegate)(在运行时之前是未知的,并且可能需要在 DOM 更改时重新计算)

最有效的方法是什么?

一点背景

我正在处理一组需要对用户事件(点击、滚动等)进行分析跟踪的页面,我希望能够在一堆页面上轻松配置这些事件处理程序,而无需编写脚本处理每个实例的事件绑定(bind)。此外,因为我将来可能需要跟踪新事件,或者跟踪动态添加到页面或从页面中删除的元素上的事件,所以我需要能够考虑在生命周期内发生的 DOM 更改页面的。

作为我目前正在考虑的示例,我想创建一个接受配置对象的函数,该配置对象允许程序员为每个事件指定默认处理程序,并允许他们为特定元素覆盖它们:

Analytics.init({
// default handlers for each event type
defaultHandlers: {
"click": function(e) { ... },
"focus": function(e) { ... }
},

// elements to listen to
targetElements: {

// it should work with non-DOM nodes like 'window' and 'document'
window: {
// events for which the default handlers should be called
useDefaultHandlers: ['click'],

// custom handler
"scroll": function(e) { ... }
},

// it should work with CSS selectors
"#someId": {
useDefaultHandlers: ['click', 'focus'],
"blur": function(e) { ... }
}
}
});

来源

最佳答案

我通常在 document.documentElement 上委托(delegate)事件反对因为:

  1. 代表<html>页面上的元素, 包含所有内容 ,其中包含用户可以与之交互的所有 HTML 标签。
  2. 它在 JavaScript 开始执行时可用,无需窗口加载或 DOM 就绪事件处理程序
  3. 您仍然可以捕获“滚动”事件

至于事件委托(delegate)的效率,事件必须冒泡的节点越多,花费的时间就越长,但是我们说的是大约 1 到 2 毫秒的时间差 -- 可能。用户是察觉不到的。引入性能损失的通常是 DOM 事件的处理,而不是事件从一个节点冒泡到另一个节点。

我发现以下因素通常会对 JavaScript 性能产生负面影响:

  1. 文档树中的节点越多,浏览器操作它所耗费的时间就越多。
  2. 页面上事件处理程序的数量越多,JavaScript 的速度就越慢,尽管您需要 100 个处理程序才能真正看到差异。

主要是,#1 的影响最大。我认为在大多数情况下,试图提高事件处理的性能是不成熟的优化。我看到的优化事件处理代码的唯一情况是你有一个每秒触发多次的事件(例如“滚动”和“mousemove”事件)。事件委托(delegate)的额外好处是您不必清理将从文档树分离的 DOM 节点上的事件处理程序,从而允许浏览器对该内存进行垃圾回收。

(来自下面的评论)wvandell 说:

The performance costs of event delegation have little to do with the actual 'bubbling' of events ... there is a performance hit incurred when delegating many selectors to a single parent.

这是事实,但让我们考虑一下感知的表现。委托(delegate)许多点击事件不会引起用户注意。如果你委托(delegate)一个像 scroll 这样的事件或 mousemove ,它可以每秒触发 50 次以上(留下 20 毫秒来处理事件),然后用户可以察觉到性能问题。这又回到了我反对过早优化事件处理程序代码的论点。

许多点击事件可以毫无问题地委托(delegate)给一个共同的祖先,例如document.documentElement .我会在那里委托(delegate)一个“mousemove”事件吗? 也许。这取决于发生了什么,以及委托(delegate)的“mousemove”事件是否足够响应。

关于javascript - 动态绑定(bind)事件处理程序的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25552804/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com