Javascript 未能覆盖元素';Firefox中的addEventListener
我试图以跨浏览器的方式覆盖元素对象的Javascript 未能覆盖元素';Firefox中的addEventListener,javascript,events,firefox,prototype,addeventlistener,Javascript,Events,Firefox,Prototype,Addeventlistener,我试图以跨浏览器的方式覆盖元素对象的addEventListener方法。这样做的目的是,我可以异步加载一些第三方脚本,这些脚本会过早地调用此方法 我创建了一个HTML文件,它在Chrome上运行得非常好,但在Firefox上我遇到了一个例外: “对WrappedNative prototype对象的非法操作”nsresult:“0x8057000c(NS\u错误\u XPC\u错误\u对WN\u PROTO的操作)” 如果您注释掉文件中更改实例方法的行,则该方法有效。但我需要在“类类型”(即原
addEventListener
方法。这样做的目的是,我可以异步加载一些第三方脚本,这些脚本会过早地调用此方法
我创建了一个HTML文件,它在Chrome上运行得非常好,但在Firefox上我遇到了一个例外:
“对WrappedNative prototype对象的非法操作”nsresult:“0x8057000c(NS\u错误\u XPC\u错误\u对WN\u PROTO的操作)”
如果您注释掉文件中更改实例方法的行,则该方法有效。但我需要在“类类型”(即原型)上进行
如有任何建议,将不胜感激
谢谢,
古柏
这是我创建的文件
<html><body>
<img id="testImg" src="http://www.blaze.io/wp-content/themes/Blaze/images/header_logoB.png">
<script>
function myLog(msg) { "undefined" != typeof(console) && console.log("Log: " + msg); }
function customListener(type, event, useCapture) {
// Register the event
myLog('Registering event');
this._origListener.apply(this, arguments);
}
// Also tried HTMLImageElement
Element.prototype._origListener = Element.prototype.addEventListener;
Element.prototype.addEventListener = customListener;
var img = document.getElementById("testImg");
// Uncommenting these lines works - but in the real case I can't access these objects
//img._origListener = img.addEventListener;
//img.addEventListener = customListener;
img.addEventListener('load',function() { myLog('load callback'); }, false);
</script>
</body>
</html>
函数myLog(msg){“undefined”!=typeof(console)&&console.log(“log:+msg);}
函数customListener(类型、事件、useCapture){
//注册活动
myLog(“注册事件”);
应用(这个,参数);
}
//还尝试了HTMLImageElement
Element.prototype.\u origListener=Element.prototype.addEventListener;
Element.prototype.addEventListener=customListener;
var img=document.getElementById(“testImg”);
//取消这些行的注释是可行的,但在实际情况下,我无法访问这些对象
//img._origListener=img.addEventListener;
//img.addEventListener=customListener;
addEventListener('load',function(){myLog('load callback');},false);
可以)typeof
是一个运算符,您不需要括号(但它不会造成伤害)元素
的原型
:这些都是主机对象,您不能依赖主机对象来公开对象的任何核心JavaScript功能。更糟糕的是,可能会有一个性能惩罚,你可能会打破其他东西。远离那种技术。有关更多信息,请阅读您希望实现什么,希望在使用第三方脚本时自动调用事件侦听器?正如Marcel所说,这与主机对象的公开方式有关。问题是,如果您重写了接口的预定义属性,那么它在继承它的接口中不会发生更改(至少在Firefox中是这样) 虽然我同意马塞尔的说法,但事实上有一种方法可以做到这一点。您应该重写要为其执行此操作的对象的最低可能接口的属性。在您的例子中,这将是
HTMLImageElement
这将实现以下目的:
(function() {
var _interfaces = [ HTMLDivElement, HTMLImageElement /* ... (add as many as needed) */ ];
for (var i = 0; i < _interfaces.length; i++) {
(function(original) {
_interfaces[i].prototype.addEventListener = function(type, listener, useCapture) {
// DO SOMETHING HERE
return original.apply(this, arguments);
}
})(_interfaces[i].prototype.addEventListener);
}
})();
(函数(){
var_interfaces=[htmldevelment,HTMLImageElement/*…(根据需要添加任意数量)*/];
对于(变量i=0;i<\u interfaces.length;i++){
(功能(原件){
_接口[i].prototype.addEventListener=函数(类型、侦听器、useCapture){
//在这里做点什么
返回原件。应用(此,参数);
}
})(_interfaces[i].prototype.addEventListener);
}
})();
我认为元素原型设计是不兼容的,我建议使用jQuery或一些框架。我同意,但我不能修改我使用的第三方脚本,所以我唯一的选择是通过更改原型来更改它们运行的JavaScript环境。我尝试运行的脚本应该作为标记异步运行。目标是使其对页面的其余部分无阻塞。脚本在页面上找到一个元素并向其添加一个加载事件侦听器,使其异步将导致脚本在加载该元素后运行。因此,我需要“捕获”事件的注册,以便检查元素是否已加载,在这种情况下,立即调用回调。所有这些都是在示例中模拟的。谢谢-我想我以前试过,但不确定。我稍后会尝试一下,然后再报告。