I started to extend the EventTarget
interface by adding some useful prototypes
but then I tested it on Safari 8 and get :
[Error] ReferenceError: Can't find variable: EventTarget
I found on MDN that "window.EventTarget
does not exist" for Safari.
This question looks really interesting but it's about IE8.
So, I want to know if a reference to the EventTarget interface is accessible on Safari, or a workaround to use code like EventTarget.prototype.hasEventListener
and EventTarget.prototype.hasEventListener
without getting any errors on Safari ?
Edit I found an interesting commit which says that it was implemented the 09/12/15 (from timestamp), but it sure doesn't work in Safari 9.1
The EventTarget interface is implemented by objects that can receive events and may have listeners for them. In other words, any target of events implements the three methods associated with this interface.
The read-only target property of the Event interface is a reference to the object onto which the event was dispatched. It is different from Event. currentTarget when the event handler is called during the bubbling or capturing phase of the event.
You're likely getting this error because you're trying to get a name attribute on elements that don't have a name attribute. For example; input, textarea, and form elements are naturally able to get a name attribute. But elements like div, span doesn't.
The target event property returns the element that triggered the event. The target property gets the element on which the event originally occurred, opposed to the currentTarget property, which always refers to the element whose event listener triggered the event.
Safari just doesn't allow you to use the EventTarget
interface in your own objects other than DOM elements. So I simply replicated the class to do it.
class EventDispatcher {
constructor() {
this._listeners = [];
}
hasEventListener(type, listener) {
return this._listeners.some(item => item.type === type && item.listener === listener);
}
addEventListener(type, listener) {
if (!this.hasEventListener(type, listener)) {
this._listeners.push({type, listener, options: {once: false}});
}
// console.log(`${this}-listeners:`,this._listeners);
return this
}
removeEventListener(type, listener) {
let index = this._listeners.findIndex(item => item.type === type && item.listener === listener);
if (index >= 0) this._listeners.splice(index, 1);
// console.log(`${this}-listeners:`, this._listeners);
return this;
}
removeEventListeners() {
this._listeners = [];
return this;
}
dispatchEvent(evt) {
this._listeners
.filter(item => item.type === evt.type)
.forEach(item => {
const {type, listener, options: {once}} = item;
listener.call(this, evt);
if (once === true) this.removeEventListener(type, listener)
});
// console.log(`${this}-listeners:`,this._listeners);
return this
}
}
I simply used the Element
interface as a fallback for Safari
var EventTarget = EventTarget || Element;
EventTarget.prototype.addEventListener = function(){/*Some magic here*/};
I also checked that Element inherits prototypes
from the EventTarget interface and it does ! (document.body.addEventListener == EventTarget.prototype.addEventListener
returned true
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With