无法在Firefox中覆盖Element的addEventListener

Guy*_*ypo 2 javascript firefox events prototype addeventlistener

我试图以addEventListener跨浏览器的方式覆盖Element对象的方法.目的是让我可以异步加载一些第三方脚本,这些脚本过早地调用这个方法.

我创建了一个在Chrome中完美运行的HTML文件,但在Firefox上我得到了以下异常:

"上WrappedNative原型对象非法操作" nsresult: "0x8057000c(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)"

如果您注释掉文件中更改INSTANCE方法的行,则它可以正常工作.但我需要在"类型"(即原型)上进行.

任何建议,将不胜感激.

谢谢,Guypo

这是我创建的文件

<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>
Run Code Online (Sandbox Code Playgroud)

Ren*_*nck 5

就像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);
    }
})();
Run Code Online (Sandbox Code Playgroud)