Do Javascript event listeners need to be removed prior to removing the element they're attached to?
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:
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")
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 recommend 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.)