Safari 中的 EventTarget 接口
EventTarget interface in safari
我开始通过添加一些有用的 prototypes
来扩展 EventTarget
界面,但后来我在 Safari 8 上对其进行了测试并得到:
[Error] ReferenceError: Can't find variable: EventTarget
我在 MDN 上发现 "window.EventTarget
对于 Safari 不存在"。
This question 看起来很有趣,但它是关于 IE8 的。
所以,我想知道是否可以在 Safari 上访问对 EventTarget 接口的引用,或者使用像 EventTarget.prototype.hasEventListener
和 [=14= 这样的代码的解决方法] 在 Safari 上没有出现任何错误?
编辑
我发现了一个有趣的 commit,它说它是在 2015 年 9 月 12 日实现的(从时间戳开始),但它肯定在 Safari 9.1
中不起作用
解决方法:
我只是使用 Element
interface 作为 Safari 的后备
var EventTarget = EventTarget || Element;
EventTarget.prototype.addEventListener = function(){/*Some magic here*/};
我还检查了 Element 从 EventTarget 接口继承了 prototypes
,确实如此! (document.body.addEventListener == EventTarget.prototype.addEventListener
返回 true
)
Safari 不允许您在自己的对象中使用 DOM 元素以外的 EventTarget
界面。所以我简单地复制了 class 来做到这一点。
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
}
}
我开始通过添加一些有用的 prototypes
来扩展 EventTarget
界面,但后来我在 Safari 8 上对其进行了测试并得到:
[Error] ReferenceError: Can't find variable: EventTarget
我在 MDN 上发现 "window.EventTarget
对于 Safari 不存在"。
This question 看起来很有趣,但它是关于 IE8 的。
所以,我想知道是否可以在 Safari 上访问对 EventTarget 接口的引用,或者使用像 EventTarget.prototype.hasEventListener
和 [=14= 这样的代码的解决方法] 在 Safari 上没有出现任何错误?
编辑 我发现了一个有趣的 commit,它说它是在 2015 年 9 月 12 日实现的(从时间戳开始),但它肯定在 Safari 9.1
中不起作用解决方法:
我只是使用 Element
interface 作为 Safari 的后备
var EventTarget = EventTarget || Element;
EventTarget.prototype.addEventListener = function(){/*Some magic here*/};
我还检查了 Element 从 EventTarget 接口继承了 prototypes
,确实如此! (document.body.addEventListener == EventTarget.prototype.addEventListener
返回 true
)
Safari 不允许您在自己的对象中使用 DOM 元素以外的 EventTarget
界面。所以我简单地复制了 class 来做到这一点。
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
}
}