我正在尝试执行某个操作,然后才会在<browser>
元素中加载指定的网址。 <browser>
可以是侧边栏或标签。
示例:(上下文是浏览器主窗口):
// it can be also browser of tab
var browser = document.getElementById("sidebar"); // <xul:browser>
// execute a function when window of browser will be prepared for loading new content but before any script will be executed
execOnWindowPrepared(browser, function(window) {
// e.g. inject something
window.foo = "bar";
});
// load an uri
browser.loadURI("chrome://foo/content/bar.xul"); // (can be also http:)
注意我无法在loadURI
语句后立即执行我的操作,因为browser.contentWindow
仍将指向旧窗口。
也许progress listeners可以用于此,但我很困惑我需要等待哪些标志。
答案 0 :(得分:0)
使用content-document-global-created or document-element-inserted notification of nsIObserverService。您使用哪一个取决于您的脚本正在做什么。如果它只是像您的示例中那样设置窗口级变量,那么content-document-global-created将是最佳的。如果您需要插入元素或以其他方式使用<html>
元素,那么插入文档元素会更好。
document-element-inserted是方法that Greasemonkey uses。
答案 1 :(得分:0)
我最终使用了这种方法。它是通过反复试验编码的,因此在某些情况下可能有问题,但我没有注意到许多测试存在任何问题。
// opens aUrl in aBrowser and call an action defined in aCallback immediately after window is prepared
function loadInBrowserWithCallback (aBrowser, aUrl, /* function(window) */ aCallback) {
var loadedUrl = nsIIOService.newURI(aUrl, null, null).spec // canonify chrome url (what mean 'canonifing': https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIChromeRegistry#canonify%28%29 )
var lastWindow = aBrowser.contentWindow;
lastWindow.__thisIsPrevWin = true;
var progressListener = {
onLocationChange : function(aWebProgress, aRequest, aLocation, aFlags) {
var window = aWebProgress.DOMWindow;
if(!window.__thisIsPrevWin && window.location.href === loadedUrl) {
// the property assigned to previus window was removed and location.href isn't any transitional url
aBrowser.removeProgressListener(this);
aCallback(window);
}
},
onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) {
var window = aWebProgress.DOMWindow;
if(!window.__thisIsPrevWin && window.location.href === loadedUrl) {
aBrowser.removeProgressListener(this);
aCallback(window);
}
},
onSecurityChange: function(aWebProgress, aRequest, aState) {
var window = aWebProgress.DOMWindow;
if(!window.__thisIsPrevWin && window.location.href === loadedUrl) {
aBrowser.removeProgressListener(this);
aCallback(window);
}
},
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
var window = aWebProgress.DOMWindow;
if(!window.__thisIsPrevWin && window.location.href === loadedUrl) {
aBrowser.removeProgressListener(this);
aCallback(window);
}
},
onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) {
var window = aWebProgress.DOMWindow;
if(!window.__thisIsPrevWin && window.location.href === loadedUrl) {
aCallback(window);
aBrowser.removeProgressListener(this);
}
},
QueryInterface: function(aIID) {
if (aIID.equals(Ci.nsIWebProgressListener) ||
aIID.equals(Ci.nsISupportsWeakReference) ||
aIID.equals(Ci.nsISupports))
return this;
throw Cr.NS_NOINTERFACE;
}
};
aBrowser.addProgressListener(progressListener, Ci.nsIWebProgress.NOTIFY_ALL);
aBrowser.loadURI(aUrl);
};