Safari中的EventTarget接口

时间:2016-04-17 11:06:12

标签: javascript safari webkit

我开始通过添加一些有用的EventTarget扩展prototypes界面,但后来我在Safari 8上测试了它并得到:

[Error] ReferenceError: Can't find variable: EventTarget

我在MDN上发现Safari的window.EventTarget不存在”

This question看起来非常有趣,但它与IE8有关。

所以,我想知道是否可以在Safari 上访问对EventTarget界面的引用,或者使用EventTarget.prototype.hasEventListenerEventTarget.prototype.hasEventListener等代码的解决方法,而不会出现任何错误在Safari?

修改 我找到了一个有趣的commit,它说它是在2015年12月9日(从时间戳)实现的,但它确实在Safari 9.1中不起作用

2 个答案:

答案 0 :(得分:3)

解决方法:

我只是使用Element interface作为Safari的后备补丁

var EventTarget = EventTarget || Element;
EventTarget.prototype.addEventListener = function(){/*Some magic here*/};

我还检查过Element从EventTarget接口继承了prototypes,它确实存在! (document.body.addEventListener == EventTarget.prototype.addEventListener返回true

答案 1 :(得分:1)

Safari不允许您在自己的除DOM元素之外的对象中使用EventTarget接口。所以我只是复制了该类来完成它。

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
    }
}