Does a javascript event handler exist in memory even after the DOM element to which it is bound is removed?

末鹿安然 提交于 2019-12-20 12:35:09

问题


Given the following code

<div id="app">
  <div id="foo" />
</div>

<script>
  $('#foo').bind('click', function(){});
</script>

I plan on replacing the contents of #app [e.g. $('#app').html('...');, or innerHTML = '...';]. I know that I can use jQuery's .remove() which calls a 'destroy' handler that unbinds events. The fact that there is a destroy handler set up to remove events leads me to believe that without unbinding the events, when the DOM element is removed, the handler will still exist in memory.

So, if the DOM element #foo no longer exists, does the handler disappear as well, or does it get lost in browser memory?


回答1:


jQuery keeps track of event handlers itself, which is part of why you need to use unbind (nowadays it's off) if you're removing the element from the DOM not through a jQuery method (if you use jQuery's empty or remove, as you mentioned it handles this itself inernally). This is so jQuery knows it can release its reference to the handler.

If it weren't for that, then in theory, you wouldn't have to do anything because once the DOM element is removed from memory, it's no longer reachable, and so in theory shouldn't keep the event handler in memory. That's the theory. The reality is very different, it can be very easy to end up with a situation (particularly on IE) where neither the DOM element nor the event handler can get cleaned up because they're each causing the other to stick around — a memory leak. JavaScript has no issue with circular references (it understands them and can release two things that are pointing to each other as long as nothing else is pointing to them), but the DOM part of the browser is likely to be written in a different language with a different garbage collection mechanism (IE uses COM, which uses reference counting rather than reachability). jQuery helps you avoid this pitfall with IE (part of why it keeps track of event handlers), but you have to use unbind (nowadays off) (or remove elements via empty, remove, etc.) as a consequence.

The take away message: As you hook, so shall you unhook. :-) (And/or use jQuery when removing elements, since it will handle this.)

Somewhat related: If you're adding and removing elements a lot, you might look to see if event delegation (which jQuery makes really easy via the delegation signatures for on) might help.




回答2:


Just happened to read the docs on jQuery's empty() method:

To avoid memory leaks, jQuery removes other constructs such as data and event handlers from the child elements before removing the elements themselves.




回答3:


Found an earlier post: Do events handlers on a DOM node get deleted with the node?



来源:https://stackoverflow.com/questions/5875622/does-a-javascript-event-handler-exist-in-memory-even-after-the-dom-element-to-wh

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!