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);
  • 请使用有效的Doctype,最好是将浏览器转换为(几乎)标准模式(
    可以)

  • typeof
    是一个运算符,您不需要括号(但它不会造成伤害)

  • 最重要的是:不要试图操纵DOM
    元素
    原型
    :这些都是主机对象,您不能依赖主机对象来公开对象的任何核心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环境。我尝试运行的脚本应该作为标记异步运行。目标是使其对页面的其余部分无阻塞。脚本在页面上找到一个元素并向其添加一个加载事件侦听器,使其异步将导致脚本在加载该元素后运行。因此,我需要“捕获”事件的注册,以便检查元素是否已加载,在这种情况下,立即调用回调。所有这些都是在示例中模拟的。谢谢-我想我以前试过,但不确定。我稍后会尝试一下,然后再报告。