我正在尝试(也许是徒劳)想出一种方法来使用发布 - 订阅模式,而 a)使用 no 库和 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] has no method 'addEventListener'
。有趣的是,即使handle将EventTarget作为其原型,它似乎也没有在原型链中查找。
为什么这不起作用?有没有办法用纯JS实现EventTarget?它可以在一行代码中完成,不会让AwesomeModule的用户感到恐惧吗?
编辑:我不知道为什么昨晚我没有发生这种情况,但我认为EventTarget是一个接口意味着它没有实现代码。令人困惑的是,在Chrome调试器控制台Object.create(EventTarget)
中,出现的对象使addEventListener成为原型链。也许是在说谎。谁能解释这种行为?谁能解释为什么W3选择不让EventTarget成为一个具体的“类”?
答案 0 :(得分:2)
看起来我原来问题的答案是肯定的。由于JavaScript没有像Java那样对合法实现进行编译时检查的继承模型,我想任何Object只能通过具有相同名称的方法来实现接口。但是,这样做会构成一个库,因为addEventListener代码没有在EventTarget中实现(我以前认为它是)。由于似乎没有跨浏览器方式来获取vanilla EventTarget,我可能会将window.addEventListener与自定义事件结合使用。
答案 1 :(得分:1)
如果您无法修改它,您可以随时复制它。
答案 2 :(得分:1)
这是一组效果很好的简单例程。 与a small polyfill for IE9 and 10一起,支持是体面的。
你可以根据需要将这些功能合并到你的项目中,我认为它不构成一个库,或者我不会发布它。
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个字符)。