Raiden
Raiden

Reputation: 411

Event listener assigned in a loop triggers all of them

Every object in the balls array is assigned an event listener that alerts the object's color, but when you click on just one, it activates all of them, alerting the color of every single object in it.

Fiddle, snippet (listen):

function listen(obj, map, event, callback) {
  map.addEventListener(event, function (e) {
    if (hasPoint(obj.getBounds() || obj, event.clientX, event.clientY)) {
      callback.call(obj, e);
    }
  });
}

Loop (handler assignment);

for (var b = 0; b < balls.length; b++) {
  (function(b) {
      listen(balls[b], map, 'click', function(e) {
        alert(this.color); // where `this` === balls[b]
      });
  }(b));
}

(note: #listen is contained in an external file on GitHub - utils.js)

How would I have each object only trigger its own event listener?

Upvotes: 0

Views: 46

Answers (1)

adeneo
adeneo

Reputation: 318182

The external util.js is key here, the listen function looks like

function listen(obj, map, event, callback) {
  map.addEventListener(event, function (e) {
    if (hasPoint(obj.getBounds() || obj, event.clientX, event.clientY)) {
      callback.call(obj, e);
    }
  });
}

And you use it like

listen(balls[b], map, 'click', function(e) {
    alert(this.color); // where `this` === balls[b]
});

Note that event in the listen() function is the string click, not the actual event, that would be e, so you want to use e to get the coordinates

function listen(obj, map, event, callback) {
  map.addEventListener(event, function (e) {
    if (hasPoint(obj.getBounds() || obj, e.clientX, e.clientY)) {
      callback.call(obj, e);
    }
  });
}

And that solves the issue

FIDDLE

Upvotes: 1

Related Questions