在删除附加的元素之前,是否需要删除javascript事件侦听器?

Jer*_*man 8 javascript events event-handling prototypejs dom-events

假设我已经将各种事件监听器附加到各种表单元素.后来,我想删除整个表单.

是否有必要(或建议)取消注册表单及其元素上存在的任何事件处理程序?如果是这样,删除元素集合上所有侦听器的最简单方法是什么?不这样做的后果是什么?如果重要的话,我正在使用Prototype.

这就是我实际在做的事情.我有一个简单的形式,像这样:

<form id="form">
  <input type="text" id="foo"/>
  <input type="text" id="bar"/>
</form>
Run Code Online (Sandbox Code Playgroud)

我观察了输入上的各种事件,例如:

$('foo').observe('keypress', onFooKeypress);
$('bar').observe('keypress', onBarKeypress);
Run Code Online (Sandbox Code Playgroud)

等等

表单通过AJAX提交,响应是表单的新副本.我将旧表单替换为新表单的副本$('form').replace(newForm).我在积累一堆活动吗?

sav*_*wer 3

是的,有一点。还不足以成为一个大问题,但旧版本的 IE 在这种情况下会泄漏。

从 Prototype 1.6.1(目前处于最终候选版本)开始,该库在页面卸载时处理此清理工作。当您使用 Prototype 添加事件观察器时,它会在数组中保留对该元素的引用;在页面卸载时,它会循环遍历该数组并删除所有观察者。

但是,如果用户要在此页面上停留一段时间,则内存使用量将在页面的生命周期内累积。您有多种选择:

  1. 侦听表单祖先上的事件,该祖先永远不会被替换。然后,在您的处理程序中,检查事件来自何处。(即“事件委托”)

  2. 在调用 之前明确取消注册所有调用Element#replace。在你的例子中,你会这样做:

    $('foo', 'bar').each(Element.stopObserving);
    
    Run Code Online (Sandbox Code Playgroud)

这相当于stopObserving不带参数调用,其效果是删除给定元素上的所有处理程序。

我会推荐选项 1。

(我们已经讨论过在 Prototype 的未来版本中自动删除侦听器,作为Element#update和的一部分Element#replace,但这是一种性能权衡。)