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