Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有没有办法用普通JS实现EventTarget?_Javascript - Fatal编程技术网

Javascript 有没有办法用普通JS实现EventTarget?

Javascript 有没有办法用普通JS实现EventTarget?,javascript,Javascript,我试图(也许是徒劳的)想出一种方法来使用发布-订阅模式,而a)不使用库,而b)最小化使用它的模块中的样板代码。到目前为止,我得出的最好的结论是: var handle = document.createElement(); var unsubscribe = AwesomeModule.subscribe(handle); handle.addEventListener('awesome', function() { console.log('awesome'); }); 这将非常有

我试图(也许是徒劳的)想出一种方法来使用发布-订阅模式,而a)不使用库,而b)最小化使用它的模块中的样板代码。到目前为止,我得出的最好的结论是:

var handle = document.createElement();
var unsubscribe = AwesomeModule.subscribe(handle);

handle.addEventListener('awesome', function() {
    console.log('awesome');
});
这将非常有效,但使用AwesomeModule的人可能会因为必须提供一个不用作元素的随机DOM元素而感到困惑

我尝试了以下方法,但效果不太好:

var handle = Object.create(EventTarget);
var unsubscribe = AwesomeModule.subscribe(handle);

handle.addEventListener('awesome', function(){
    console.log('awesome')
});
我得到
TypeError:Object[Object Object]没有方法“addEventListener”
。有趣的是,尽管handle将EventTarget作为其原型,但它似乎并没有查看原型链

为什么这样不行?有没有办法用纯JS实现EventTarget?它可以在一行代码中完成,而不会吓坏AwesomeModule的用户吗


EDIT:我不知道为什么我昨晚没有想到,但我认为EventTarget作为一个接口意味着它没有实现代码。令人困惑的是,在Chrome调试器控制台中,Object.create(EventTarget)生成一个对象,该对象似乎在is原型链中包含addEventListener。也许是撒谎。有人能解释这种行为吗?有人能解释为什么W3选择不让EventTarget成为一个具体的“类”吗?

源代码位于这里:


如果您不能修改它,您可以随时复制它。

这里有一组简单的例程,运行良好。 有了这些,支持是体面的

您可以根据需要将这些函数合并到您的项目中,我不认为它构成了一个库,或者我不会发布这篇文章

var on = addEventListener.bind(window),
 off = removeEventListener.bind(window),
 emit = function(name, val) {
    dispatchEvent(new CustomEvent(name, {
        detail: val
    }));
};



// demo:
on("test", function(e){ alert(e.detail);});
emit("test", "Number is " + Math.random());

我认为在不牺牲速度或库兼容性的情况下,它不可能变得更简单(~180个字符)。

我最初的问题的答案似乎是“是”。因为JavaScript没有像Java那样的继承模型,Java会对合法实现进行编译时检查,我想任何对象都可以实现一个接口,只要有同名的方法。然而,这样做将构成创建一个库,因为addEventListener代码没有在EventTarget中实现(我以前假设是这样)。由于似乎没有跨浏览器的方式来获取vanilla EventTarget,我可能会将window.addEventListener与自定义事件结合使用。

Internet Explorer 6、7和8不支持addEventListener。您需要使用attachEvent。对于同时支持这两种功能的库函数,您可以使用位于://--@MattBall的函数,它是浏览器JS:@jeff的核心部分。我现在不关心浏览器的兼容性。我在Chrome上遇到了这个问题。看起来很方便,但它仍然使用DOM元素。我可能会最终使用这样的东西,但我不确定我认为这是对我的问题的回答。它在哪里使用任何DOM元素?你使用窗口作为一个全局事件调度器。正如我所说,您的方法很有用,因为它对模块用户隐藏了DOM诡计,但我真的希望找到一种将事件绑定到非DOM对象的方法。基本EventEmitter不使用window(它不是元素imho),但这至少需要一个小库。Node.js有一个非常好的开源EventEmitter,如果您担心窗口导致的问题,我会咬紧牙关使用它。bower和microsjs上列出了几个较小的。这是一个可以证明的更好的方法来解决你的问题…@dandavis你有这些LIB的链接吗?这很有趣。这是否意味着您可以在Chromium中拥有一个“具体”的目标?新链接: