0

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?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Raiden
  • 311
  • 3
  • 17
  • It looks like you're adding the event listener to map in the listen() function. Instead, maybe try obj.addEventListener( ... – miir Feb 23 '16 at 02:21
  • `obj` is just a JavaScript object -- not a DOM element. It doesn't have #addEventListener. – Raiden Feb 23 '16 at 02:24
  • I see.. then I think the problem is your if-condition: hasPoint(obj.getBounds() || obj, event.clientX, event.clientY)) ...what is this hasPoint function doing, and what does obj.getBounds() || obj do ? It looks like all of the objects are returning true for that conditional check.. – miir Feb 23 '16 at 02:30
  • may be this answer must help you out solve the issue. http://stackoverflow.com/questions/9880279/how-do-i-add-a-simple-onclick-event-handler-to-a-canvas-element – Rajshekar Reddy Feb 23 '16 at 02:41
  • No, my calculations are fine for detecting clicks on the balls. It's just the event fires for every ball, not just the one that was clicked. – Raiden Feb 23 '16 at 02:44
  • Also, @miir, the `hasPoint` function returns whether or not the bounding rectangle of the object contains the mouse coordinates. It passes in the object itself if it doesn't have `#getBounds`, and assumes that it IS a rectangle with `width` and `height `properties. I don't think it is returning true for every object since I have an IIFE wrapping the listener which takes care of that particularly common problem. – Raiden Feb 23 '16 at 02:52

1 Answers1

1

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

adeneo
  • 312,895
  • 29
  • 395
  • 388