我正在构建一个Firefox扩展程序,除其他外,需要在一个网站上替换正文背景颜色。我对主要在Firefox 4上工作的方法感兴趣,与旧版Firefox的兼容性并不重要。
我已经在Chrome,Opera和Safari扩展程序中完成了这项工作,但经过几个小时的阅读和尝试各种内容后,我无法在Firefox扩展程序中执行相同的操作。请帮忙。
我提前为这么长的帖子道歉,我试图尽可能地缩短它。
到目前为止我尝试了什么:
这种方法确实取代了颜色但是它做得太晚了,Firefox首先显示原始颜色,然后用我的颜色替换它。看来我的功能直到该网站的adsense或facebook小部件完成他们的工作才会执行。如果用户有某种广告拦截器而不是正常工作,但这显然对我的扩展没有任何意义。
gBrowser.addEventListener("DOMContentLoaded", my_function, true);
my_function: function(event)
{
var doc = event.originalTarget;
doc.body.style.background = "#f00";
}
我尝试了这三种观察者类型:
我无法从任何列出的观察者中访问body元素。
Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService).addObserver(
{
observe: function(aSubject, aTopic, aData)
{
var doc = aSubject;
// doc.location - contains the url
// doc - [object XrayWrapper [object Window]]
// doc.document - [object XrayWrapper [object HTMLDocument]]
// doc.document.body - null
doc.document.body.style.background = "#f00"; // this will obviously not work because body is not yet created or I'm looking in the wrong place
}
}, "content-document-global-created", false);
从STATE_TRANSFERRING我无法访问正文,从STATE_STOP开始为时已晚。
browser.webProgress.addProgressListener(this, browser.webProgress.NOTIFY_STATE_DOCUMENT);
onStateChange: function(aWebProgress, aRequest, aFlag, aStatus)
{
var doc = aWebProgress.DOMWindow;
if (aFlag & Components.interfaces.nsIWebProgressListener.STATE_TRANSFERRING)
{
// doc.document.body - null
doc.document.body.style.background = "#f00"; // again this will obviously not work because body is not yet created or I'm looking in the wrong place
}
if (aFlag & Components.interfaces.nsIWebProgressListener.STATE_STOP)
{
// doc.document.body - [object XrayWrapper [object HTMLBodyElement]]
doc.document.body.style.background = "#f00"; // works but the same way DOMContentLoaded does, too slow
}
}
这确实会立即改变颜色,但我为用户访问的每个网站和资源都获得了很多事件,我不习惯使用这个简单的事情来改变一个网站的背景颜色。
browser.webProgress.addProgressListener(this, browser.webProgress.NOTIFY_PROGRESS);
onProgressChange: function(aWebProgress, aRequest, curSelf, maxSelf, curTot, maxTot)
{
var doc = aWebProgress.DOMWindow;
doc.document.body.style.background = "#f00";
}
是否有任何其他方法可以在创建后立即访问body元素? 或者可能是其他一些方法来改变网页样式(当然不涉及其他一些扩展)? 我可以以某种方式将NOTIFY_PROGRESS监听器附加到一个网站吗?
答案 0 :(得分:2)
最后,我做了一些不应该对性能产生很大影响的东西,它会立即改变背景颜色。
我做了两个听众: NOTIFY_LOCATION 和 NOTIFY_PROGRESS 。我使用第一个(NOTIFY_LOCATION)来查看用户何时打开网站我正在尝试更改颜色,一旦用户打开该网站,我在该选项卡上设置了NOTIFY_PROGRESS监听器。从NOTIFY_PROGRESS监听器内部检查是否存在body元素,只要body可以访问,我就设置颜色并删除NOTIFY_PROGRESS监听器,因为我不再需要它了。
listener_location =
{
init: function()
{
gBrowser.browsers.forEach(function(browser)
{
browser.webProgress.addProgressListener(this, browser.webProgress.NOTIFY_LOCATION);
}, this);
gBrowser.tabContainer.addEventListener("TabOpen", this, false);
gBrowser.tabContainer.addEventListener("TabClose", this, false);
},
uninit: function()
{
gBrowser.browsers.forEach(function(browser)
{
browser.webProgress.removeProgressListener(this);
}, this);
gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
gBrowser.tabContainer.removeEventListener("TabClose", this, false);
},
handleEvent: function(aEvent)
{
var tab = aEvent.target;
var webProgress = gBrowser.getBrowserForTab(tab).webProgress;
if (aEvent.type === "TabOpen")
{
webProgress.addProgressListener(this, webProgress.NOTIFY_LOCATION);
}
else
{
webProgress.removeProgressListener(this);
}
},
QueryInterface: function(aIID)
{
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
},
onLocationChange: function(aProgress, aRequest, aURI)
{
if (aURI.host.indexOf("www.example.com") !== -1)
{
aProgress.addProgressListener(listener_progress, aProgress.NOTIFY_PROGRESS);
}
}
};
listener_location.init();
listener_progress =
{
QueryInterface: function(aIID)
{
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
},
onProgressChange: function(aWebProgress, aRequest, curSelf, maxSelf, curTot, maxTot)
{
if (aWebProgress.DOMWindow.document.body)
{
aWebProgress.removeProgressListener(this); // remove listener
var doc = aWebProgress.DOMWindow.document;
doc.body.style.background = "#f00"; // set color
}
}
};
如果其他人试图使用此代码,那么阅读这些代码可能会有用:
https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads
https://developer.mozilla.org/en/Code_snippets/Progress_Listeners
https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIWebProgressListener
答案 1 :(得分:0)
在显示之前,可能无法将手放在body元素上,因此您可以更改CSS样式。另一种方法是向文档样式表添加新规则,您应该可以通过Web进度监听器中的document.styleSheets来执行该规则。只需添加一个规则(使其成为必要的重要部分),强制身体的背景为您想要的颜色,并在显示正文时应用它。