最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Do Javascript event listeners need to be removed prior to removing the element they're attached to? - Stack Overflow

programmeradmin0浏览0评论

Suppose I have attached a variety of event listeners to various form elements. Later, I want to remove the entire form.

Is it necessary (or suggested) to unregister any event handlers that exist on the form and its elements? If so, what is the easiest way to remove all listeners on a collection of elements? What are the repercussions of not doing so? I'm using Prototype, if it matters.

Here's what I'm actually doing. I have a simple form, like this:

<form id="form">
  <input type="text" id="foo"/>
  <input type="text" id="bar"/>
</form>

I observe various events on the inputs, e.g.:

$('foo').observe('keypress', onFooKeypress);
$('bar').observe('keypress', onBarKeypress);

etc.

The form is submitted via AJAX and the response is a new copy of the form. I replace the old form with a copy of the new one doing something like $('form').replace(newForm). Am I accumulating a bunch of event cruft?

Suppose I have attached a variety of event listeners to various form elements. Later, I want to remove the entire form.

Is it necessary (or suggested) to unregister any event handlers that exist on the form and its elements? If so, what is the easiest way to remove all listeners on a collection of elements? What are the repercussions of not doing so? I'm using Prototype, if it matters.

Here's what I'm actually doing. I have a simple form, like this:

<form id="form">
  <input type="text" id="foo"/>
  <input type="text" id="bar"/>
</form>

I observe various events on the inputs, e.g.:

$('foo').observe('keypress', onFooKeypress);
$('bar').observe('keypress', onBarKeypress);

etc.

The form is submitted via AJAX and the response is a new copy of the form. I replace the old form with a copy of the new one doing something like $('form').replace(newForm). Am I accumulating a bunch of event cruft?

Share Improve this question edited Jul 21, 2019 at 18:03 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Jul 16, 2009 at 15:52 Jeremy KauffmanJeremy Kauffman 10.4k5 gold badges43 silver badges53 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

Events which are not unregistered may not free their memory automatically. This is especially a problem in older versions of IE.

Prototype used to have an automatic garbage collection system for this, but the method has been removed in version 1.6. It is documented here. Whether the removal of the method means that the garbage collection no longer takes place, or the method just isn't publicly available anymore, I don't know. Also note that it was only ever called on page unload, meaning that if your users stay on the same page for a long time while doing a lot of AJAX and DOM updates, memory may leak to an unacceptable extent even during that one page visit.

Yeah, a bit. Not enough to be a huge problem, but older versions of IE will leak under those circumstances.

As of Prototype 1.6.1 (currently in its final release candidate), the library handles this cleanup on page unload. When you use Prototype to add an event observer, it keeps a reference to that element in an array; on page unload, it loops through that array and removes all your observers.

However, if the user is going to stay on this page for a while, memory usage will accumulate over the life of the page. You have several options:

  1. Listen for events on an ancestor of the form, one that never gets replaced. Then, in your handler, check where the event came from. (i.e., "event delegation")

  2. Explicitly un-register all your calls before calling Element#replace. In your example, you'd do:

    $('foo', 'bar').each(Element.stopObserving);
    

This is equivalent to calling stopObserving with no arguments, which has the effect of removing all handlers on a given element.

I would remend option 1.

(We've talked about doing automatic listener removal in a future version of Prototype as part of Element#update and Element#replace, but it's a performance trade-off.)

It's always good to remove any event listeners from elements that are removed from the DOM in case of the scenario that Jonas mentioned below.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论