如何从 Firefox 扩展覆盖 JavaScript 函数?
我试图拦截所有页面对 document.write 的调用。通过注入像这样的脚本在页面内设置拦截
function overrideDocWrite() {
alert("Override called");
document.write = function(w) {
return function(s) {
alert("special dom");
w.call(this, wrapString(s));
};
}(document.write);
alert("Override finished");
}
很简单并且有效,但我希望我的扩展能够从扩展内部为每个文档对象设置拦截。我找不到办法做到这一点。我尝试监听“load”事件并在那里设置拦截,但它也失败了。如何从扩展中挂钩对 doc.write
的调用?
我取得了一些进展:
var myExtension = {
init: function() {
var appcontent = document.getElementById("appcontent"); // browser
if (appcontent)
appcontent.addEventListener("DOMContentLoaded", myExtension.onPageLoad,
true);
},
onPageLoad: function(aEvent) {
var doc = aEvent.originalTarget; // doc is document that triggered "onload" event
// do something with the loaded page.
// doc.location is a Location object (see below for a link).
// You can use it to make your code executed on certain pages only.
alert("Override called");
alert(doc);
alert(doc.write);
alert(doc.wrappedJSObject);
alert(doc.wrappedJSObject.write);
doc.wrappedJSObject.write = function(w) {
return function(s) {
alert("special dom");
w.call(this, "(" + s + ")");
};
}(doc.write);
alert("Override finished");
}
}
这似乎有效,但 DOMContentLoaded 是该作业的错误事件,因为它被触发得太晚了!有更早的活动可以听吗?
I am trying to intercept calls to document.write for all pages. Setting up the interception inside the page by injecting a script like
function overrideDocWrite() {
alert("Override called");
document.write = function(w) {
return function(s) {
alert("special dom");
w.call(this, wrapString(s));
};
}(document.write);
alert("Override finished");
}
Is easy and works, but I would like my extension to setup the interception for each document object from inside the extension. I couldn't find a way to do this. I tried to listen for the "load" event and set up the interception there but it also fails. How do I hook calls to doc.write
from an extension?
I made some progress:
var myExtension = {
init: function() {
var appcontent = document.getElementById("appcontent"); // browser
if (appcontent)
appcontent.addEventListener("DOMContentLoaded", myExtension.onPageLoad,
true);
},
onPageLoad: function(aEvent) {
var doc = aEvent.originalTarget; // doc is document that triggered "onload" event
// do something with the loaded page.
// doc.location is a Location object (see below for a link).
// You can use it to make your code executed on certain pages only.
alert("Override called");
alert(doc);
alert(doc.write);
alert(doc.wrappedJSObject);
alert(doc.wrappedJSObject.write);
doc.wrappedJSObject.write = function(w) {
return function(s) {
alert("special dom");
w.call(this, "(" + s + ")");
};
}(doc.write);
alert("Override finished");
}
}
This seem to work, but DOMContentLoaded is the wrong event for the job, because it is fired too late! Is there an earlier event to listen to?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
复活的问题!我得到了答案。以下是示例代码:
从 gecko 2.0 开始,具有事件 document-element-inserted 的文档也是如此。
Ressurection of the question ! I got the answer. Here is a sample code :
The same goes for document with the event document-element-inserted as of gecko 2.0 .
JavaScript 使用原型继承系统,对象没有类,而是有原型。原型是真实的对象,用作对其他对象的引用以继承方法和属性。
最好的策略是重写“文档”原型中写入的方法(对于 HTML 文档来说是 HTMLDocument)。这应该有效地包装浏览器中加载的页面内“文档”的所有实例的方法,因为它们都使用相同的原型。
而不是
尝试这样的事情:
更新:它似乎并不像我最初想象的那么容易,这似乎在第一次尝试时不起作用。
JavaScript uses a prototypical inheritance system, instead of having classes, objects have prototypes. Prototypes are real objects that are used as a reference to other objects for inheritance of methods and attributes.
The best strategy would be to override the method write in the prototype of "document" (which for the HTML document is HTMLDocument). This should effectively wrap the method for all instances of "document" inside the pages loaded in the browser since they all use the same prototype.
Instead of
try something like this:
UPDATE: It does not seem to be as easy as I initially thought, this does not seem to work at first try.