diff --git a/event-dispatcher.js b/event-dispatcher.js index 7c570e2..365515b 100644 --- a/event-dispatcher.js +++ b/event-dispatcher.js @@ -81,7 +81,7 @@ class EventDispatcher listener: listener, thisObject: (thisObject ? thisObject : this), useCapture: (useCapture ? true : false) - }; + }; target.push(obj); @@ -151,11 +151,19 @@ class EventDispatcher event[name] = src[name]; } } + + function getParent(subject) + { + if("eventDispatcherParent" in subject) + return subject.eventDispatcherParent; + + return subject.parent; + } event.target = this; var path = []; - for(var obj = this.parent; obj != null; obj = obj.parent) + for(var obj = getParent(this); obj != null; obj = getParent(obj)) path.unshift(obj); event.phase = Event.CAPTURING_PHASE; @@ -174,7 +182,7 @@ class EventDispatcher // Native DOM event var topMostElement = this.element; - for(var obj = this.parent; obj != null; obj = obj.parent) + for(var obj = getParent(this); obj != null; obj = getParent(obj)) { if(obj.element) topMostElement = obj.element; @@ -263,14 +271,20 @@ class EventDispatcher if(!(arr = this._listenersByType[event.type])) return; - for(var i = 0; i < arr.length; i++) + // Create a copy of the array, in case any listeners are unbound during iteration + var chain = arr.slice(); + + for(var i = 0; i < chain.length; i++) { - obj = arr[i]; + obj = chain[i]; + + if(arr.indexOf(obj) == -1) + continue; // Listener has been unbound if(event.phase == Event.CAPTURING_PHASE && !obj.useCapture) continue; - obj.listener.call(arr[i].thisObject, event); + obj.listener.call(chain[i].thisObject, event); } } } diff --git a/package.json b/package.json index 912c523..fce2476 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@perry-rylance/event-dispatcher", - "version": "1.0.1", + "version": "1.0.2", "description": "A lightweight ES6 event dispatcher which supports bubbling, capture phases and bubbling to the DOM tree.", "main": "event-dispatcher.js", "type": "module",