Note that there are some explanatory texts on larger screens.

plurals
  1. POUnbind inline javascript events from HTML elements in memory
    text
    copied!<p><strong>How do I completely unbind inline javascript events from their HTML elements?</strong></p> <p>I've tried:</p> <ul> <li>undelegating the event from the body element</li> <li>unbinding the event from the element</li> <li>and even removing the event attribute from the HTML element</li> </ul> <p>To my surprise at least, only removing the <code>onchange</code> attribute (<code>.removeAttr('onchange')</code>) was able to prevent the event from firing again.</p> <pre><code>&lt;input type="text" onchange="validateString(this)"&gt;&lt;/input&gt; </code></pre> <p><em>I know this is possible with delegates and that's probably the best way to go, but just play along here. This example is purely hypothetical just for the sake of proposing the question.</em></p> <hr> <p>So the hypothetical situation is this:</p> <p>I'm writing a javascript validation library that has javascript events tied to input fields via inline HTML attributes like so:</p> <pre><code>&lt;input type="text" onchange="validateString(this)"&gt;&lt;/input&gt; </code></pre> <p>But, I'd like to make the library a little better by unbinding my events, so that people working with this library in a single-page application don't have to manage my event handlers and so that they don't have to clutter their code at all by wiring up input events to functions in my hypothetical validation library... whatever. None of that's true, but it seems like a decent usecase. <br /><br /></p> <p>Here's the "sample" code of Hypothetical Validation Library.js: <br /> <strong><h3><a href="http://jsfiddle.net/CoryDanielson/jwTTf/" rel="nofollow noreferrer">http://jsfiddle.net/CoryDanielson/jwTTf/</a></h3></strong><br /> To test, just type in the textbox and then click elsewhere to fire the change event. Do this with the web inspector open and recording on the Timeline tab. Highlight the region of the timeline that correlates to when you've fired the change event (fire the change event multiple times) and you'll see the event listeners (in the window below) increase by 100 on each change event. If managed &amp; removed properly, each event listener would be properly removed before rendering a new input, but I have not found a way to properly do that with inline javascript events.</p> <p>What that code does is this:</p> <ol> <li>onChange, the input element triggers a validation function</li> <li>That function validates the input and colors the border if successful</li> <li><p>Then after 1 second (to demonstrate the memory leak) the input element is replaced with identical HTML 100 times in a row without unbinding the change event (because I don't know how to do that.. that's the problem here). This simulates changing the view within a single-page app. This creates 100 new eventListeners in the DOM, which is visible through the web inspector.</p> <ul> <li>Interesting Note. <code>$('input').removeAttr('onchange');</code> will actually prevent the onchange event from being fired in the future, but <strong>does not</strong> garbage collect the eventListener/DOM stuff that is visible in the web inspector.</li> </ul></li> </ol> <p>This screenshot is after change event fires 3 times. Each time, 100 new DOM nodes are rendered with identical HTML and I've attempted to unbind the <code>onchange</code> event from each node before replacing the HTML.</p> <p><img src="https://i.stack.imgur.com/OAjHR.png" alt="enter image description here"></p> <hr> <p><strong>Update:</strong> I came back to this question and just did a quick little test using the JSFiddle to make sure that the answer was valid. I ran the 'test' dozens of times and then waited -- sure enough, the GC came through and took care of business.</p> <p><img src="https://i.stack.imgur.com/Dupgt.png" alt="enter image description here"></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload