5

An event associated with an item is removed if you also remove the element with removeChild()? Even if the item is removed with a simple this.innerHTML =''? The same applies to an event associated to an inline element like this <div onclick="/*this event*/"> </div>? Thanks in advance.

user2809046
  • 55
  • 1
  • 6
  • I just want to know if they remain the same in memory... – user2809046 Sep 24 '13 at 16:02
  • I think it depends from browser and its garbage collector.... but i'm not sure – Luca Rainone Sep 24 '13 at 16:03
  • `removeChild()` - it removes all the info inside element and of course it removes it's `onclick` etc – el Dude Sep 24 '13 at 16:07
  • 2
    @EL [Are you sure](http://jsfiddle.net/Hm8GE/2/)? – Teemu Sep 24 '13 at 16:21
  • 1
    So in short what are the 3 answers to my 3 questions? – user2809046 Sep 24 '13 at 16:35
  • why not just remove the listeners like you're supposed to ? – dandavis Sep 24 '13 at 16:40
  • @Teemu I think so. If anyone explain me how to invoke `onclick()` of some element when that element is deleted, I'd take back my words =) – el Dude Sep 24 '13 at 21:12
  • 1
    @EL Well, you can't click on a deleted element, but as you can see in my fiddle, a removed element can be returned. An event handler still consumes memory, if there's a reference to the removed element. How much, is a different thing. If there's a named function to handle an event, it'll be there after deleting the element too. Keeping just a reference to a handler function consumes only few bytes... My comment to you (and the fiddle) was posted just to show, that `removeChild()` doesn't necessarily remove the element in its argument from the memory. – Teemu Sep 24 '13 at 21:25
  • @Teemu Sincerelly, I was surprized that `removeChild()` doesnt removes, so I'll delete my previuos statements, but I'm sure when it's cleared via `innerHTML=''` that it's really cleared. Or? .....oops, can't delete it. – el Dude Sep 26 '13 at 11:08
  • 1
    @EL Not even with removing `innerHTML` of the parent element. Please check the linked fiddle in my comment to Krasimir's answer. Only if there's no reference to the element, it's really removed. – Teemu Sep 26 '13 at 11:24

2 Answers2

9

The answer is that it depends whether you have references to it or not.

var d = document.createElement('div');
otherElement.appendChild(d);
otherElement.removeChild(d);
// still have reference to d, it will exist, event listener remains even if it won't be fired.

If you no longer have a way to access it, the element will be garbage collected along with the listeners (for all browsers > IE6).

Tibos
  • 27,507
  • 4
  • 50
  • 64
  • Also in IE<7, if there's not an existing reference to the element in the event handler itself. I.e. there's not a variable declared like `var elem = event.srcElement;` In IE<7 `elem` causes a memory leak, when removing the element having this handler. – Teemu Sep 24 '13 at 16:58
6

I made the following test:

<div class="wrapper">
    <a href="#">Link</a>
</div>
<script type="text/javascript">
    window.onload = function() {
        var wrapper = document.querySelector(".wrapper");
        var link = document.querySelector("a");
        link.addEventListener("click", function() {
            console.log("click");
        });
        setTimeout(function() {
            wrapper.innerHTML = "";
        }, 4000)
    }
</script>

and monitor the results in the dev tools. After the loading of the page the events attached become from 5 to 6. The link is removed from the DOM and the events listeners become 5 again.

enter image description here

Krasimir
  • 13,306
  • 3
  • 40
  • 55
  • So inline events are also removed with innerHTML right? – user2809046 Sep 24 '13 at 16:33
  • @user2809046 [Nothing is really removed](http://jsfiddle.net/Hm8GE/3/), if you still have a reference to the element, as said in Tibos' answer. In case there's no reference, the element and its members are removed ofcourse. – Teemu Sep 24 '13 at 16:35
  • So you advise me to remove the events manually? And how do to events inline? – user2809046 Sep 24 '13 at 16:37
  • @user2809046 Inliners are gone with the element too. Just take care, there's not a reference to the element (like global `but` in my fiddle), and you can safely remove the element only. If there is a reference, you can remove the eventlisteners manually, but the element itself remains in the memory, no matter what you'll do..., except when removing the reference too. – Teemu Sep 24 '13 at 16:40
  • I just run the same test but with inline click handler. The handler wasn't even counted by the Chrome's timeline, which is kinda interesting. – Krasimir Sep 24 '13 at 16:41
  • @Krasimir I guess that's because an inline event handler is just a value of an attribute. – Teemu Sep 24 '13 at 16:43
  • In practice, I should leave everything as it is, right? – user2809046 Sep 24 '13 at 16:51
  • @user2809046 I'd test the code in the same way as Krasimir has done. Then you can be sure. Like said many times here, removing depends on the existing references to the element... – Teemu Sep 24 '13 at 16:55