Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

var a = function() vs function a() for event listener?

I'm trying to understand the difference when adding a function to an event listener and what implications it has.

var buttons = document.getElementsByTagName('button');
for (i = 0, len = 3; i < len; i++) {
    var log = function(e) {
        console.log(i);
    }
    buttons[0].addEventListener("click", log);
}

for (i = 0, len = 3; i < len; i++) {
    function log(e) {
        console.log(i);
    }
    buttons[1].addEventListener("click", log);
}

http://jsfiddle.net/paptd/

The first button fires the console.log 3 times while the second only fires it once.

Why and what should you use when adding a function to an event listener in a normal situation?

like image 595
user1767586 Avatar asked Oct 04 '22 23:10

user1767586


1 Answers

Well, couple of notes:

  • The first one creates a new log function in each iteration, so every time you add another event listener it adds a new function.
  • The second one creates a global(read about hoisting) log function, If multiple identical EventListeners are registered on the same EventTarget with the same parameters, the duplicate instances are discarded. They do not cause the EventListener to be called twice.

Specs:

Invoking addEventListener (or removeEventListener) repeatedly on the same EventTarget with the same values for the parameters type, listener, and useCapture has no effect. Doing so does not cause the event listener to be registered more than once and does not cause a change in the triggering order.

source thanks to Rob W.

so the second and third iterations do nothing.

  • You also have a problem of closure, the last iteration sets i to 3 and this is what shown in the console.

Fixed version with closure:

var buttons = document.getElementsByTagName('button');
for (i = 0, len = 3; i < len; i++) {
    var log = (function closure(number) {
        return function () {
            console.log(number);
        }
    })(i);

    buttons[0].addEventListener("click", log);
}

DEMO

like image 60
gdoron is supporting Monica Avatar answered Oct 13 '22 11:10

gdoron is supporting Monica