Javascript 是否可以扩展EventTarget接口?
我正在寻找一个答案,如果这是可能的,甚至是一个好主意 通常,作为IE8和早期版本的修复,会使用类似的解决方法:Javascript 是否可以扩展EventTarget接口?,javascript,javascript-events,addeventlistener,Javascript,Javascript Events,Addeventlistener,我正在寻找一个答案,如果这是可能的,甚至是一个好主意 通常,作为IE8和早期版本的修复,会使用类似的解决方法: var addEvent = function(obj, e, cb) { if(obj.attachEvent) { return obj.attachEvent('on' + e, cb); } else { obj.addEventListener(e, cb, false); return true; }
var addEvent = function(obj, e, cb) {
if(obj.attachEvent) {
return obj.attachEvent('on' + e, cb);
} else {
obj.addEventListener(e, cb, false);
return true;
}
}
然后程序员总是使用addEvent
而不是addEventListener
是否有任何方法或点可以创建一个addEventListener
函数,当attachEvent
未定义时,该函数将环绕该attachEvent
我认为这有点棘手,因为EventTarget可以是DOM元素、文档、窗口或其他东西。这取决于您要返回的距离。在IE8上,您可以扩展
Element.prototype
以向所有HTML元素添加功能,这至少是90%的工作量。我相当肯定你在IE6中做不到这一点(PrototypeJS不得不求助于扩展单个元素实例),我不记得IE7了。除非你瞄准东亚市场,否则你基本上可以忽略IE7和更早的版本
下面是一个如何做到这一点的示例:
(function() {
// Functions for IE
function stopPropagation() {
this.cancelBubble = true;
}
function preventDefault() {
this.returnValue = false;
}
function addEventUsingAttach(eventName, handler)
{
this.attachEvent("on" + eventName, function() {
var e = window.event;
e.stopPropagation = stopPropagation;
e.preventDefault = preventDefault;
handler.call(this, e);
});
}
// Function to add `addEvent` to the given target object
function extendIt(target)
{
if (target.addEventListener) {
target.addEvent = Element.prototype.addEventListener;
}
else {
target.addEvent = addEventUsingAttach;
}
}
// Add it to `Element.prototype` if we have it
if (typeof Element !== "undefined" &&
typeof Element.prototype !== "undefined") {
extendIt(Element.prototype);
}
// Add it to `window` and `document` (etc.)
extendIt(window);
extendIt(document);
})();
|
然后手动扩展其他事件目标,如窗口
和文档
(请参见上面代码列表的末尾)
原始答案:我最初误解了你的问题是关于添加addEventListener
,特别是在IE8上,而事实上你的问题很明显不是关于添加那个,而是添加你自己的addEvent
。我将这个答案留给其他读者:
这取决于你想走多远。在IE8上,您可以扩展Element.prototype
以向其中添加addEventListener
,页面上的所有HTML元素都将使用它(见下文)。不过,您添加的垫片无法支持捕获阶段,因为IE在本机支持addEventListener
之前不支持它。我相当肯定你不能扩展元素。prototype
在早期版本(IE7、IE6)上,PrototypeJS不得不退回到为旧版本的IE扩展特定元素上。但它在IE8中工作
扩展了Element.prototype
,则必须手动扩展您提到的其他事件目标,但扩展Element.prototype
完成了大部分工作
但是,如果您这样做并且包含第三方脚本,请注意,它们可能会假定在捕获阶段完成了addeventlistener
的正确实现
下面是一个用于将addEventListener
添加到IE8的基本垫片:
(function() {
function stopPropagation() {
this.cancelBubble = true;
}
function preventDefault() {
this.returnValue = false;
}
if (typeof Element !== "undefined" &&
typeof Element.prototype !== "undefined" &&
!Element.prototype.addEventListener) {
Element.prototype.addEventListener = function(eventName, handler, useCapture) {
if (useCapture) {
throw "Browser doesn't support capturing phase";
}
this.attachEvent("on" + eventName, function() {
var e = window.event;
e.stopPropagation = stopPropagation;
e.preventDefault = preventDefault;
handler.call(this, e);
});
};
}
})();
|通常,可以通过将函数附加到对象来将函数添加到对象
obj.addEventListener = function(/* args*/) { /* body */ }
或者将函数附加到对象构造函数的原型
EventTarget.prototype.addEventListener = function(/* args*/) { /* body */ }
使用前者,添加的函数只能在特定对象上调用,而使用后者,您可以在所有对象上调用该函数,这些对象是从该特定对象构造函数创建的
但是,
- EventTargets是主机对象,因此是否可以将函数添加到此类对象取决于实现
- EventTargets是主机对象,因此它取决于
EventTarget.prototype是否实际存在,并且与本机对象具有相同的含义
- 如果对象符合
EventTarget
接口,则它很可能已经具有addEventListener
功能
- 使用
attachEvent
附加的事件侦听器与使用addEventListener
添加的事件侦听器具有不同的参数
最后,尝试使用JavaScript使一个具有蹩脚DOM的浏览器支持更高的标准兼容性是不可行的。typeof EventTarget
是“未定义的”
,即使在Chrome上,更不用说IE8了。实际上,T.J.我最初的意思是我可以包含类似于IE8脚本的内容(我完全赞成忽略之前的版本),然后正常使用addEventListener
(不在IE8中捕获)。重点是避免使用命名独特的addEvent,而是使用基于标准的vanilla JS。