Firefox addon 页面完全加载后加载脚本

Firefox addon 页面完全加载后加载脚本,firefox-addon,Firefox Addon,我正在构建一个firefox插件,在每次加载页面时加载javascript。我正在使用在此页面上找到的进度侦听器函数: 我的问题是代码似乎在页面完全加载之前就执行了,这导致我的脚本无法运行。这是我的密码 var PageLoad={ 浏览器:空, 域:空, oldURL:null, init:function(){ gBrowser.addProgressListener(urlBarListener,Components.interfaces.nsIWebProgress.NOTIFY_LOC

我正在构建一个firefox插件,在每次加载页面时加载javascript。我正在使用在此页面上找到的进度侦听器函数:

我的问题是代码似乎在页面完全加载之前就执行了,这导致我的脚本无法运行。这是我的密码

var PageLoad={
浏览器:空,
域:空,
oldURL:null,
init:function(){
gBrowser.addProgressListener(urlBarListener,Components.interfaces.nsIWebProgress.NOTIFY_LOCATION);
},
uninit:function(){
gBrowser.removeProgressListener(urlBarListener);
},
processNewURL:函数(aURI){
//if(aURI.spec==this.oldURL)
//返回;
MyObject.function();
this.oldURL=aURI.spec;
}
};
var urlBarListener={
locChange:false,
QueryInterface:函数(aIID){
if(aIID.equals(Components.interfaces.nsIWebProgressListener)||
aIID.equals(Components.interfaces.nsisupportsWakReference)||
aIID.equals(组件.接口.支持))
归还这个;
抛出组件.results.NS\n接口;
},
onLocationChange:功能(进程、请求、aURI){
PageLoad.processNewURL(aURI);
},
onStateChange:function(aWebProgress、aRequest、aFlag、aStatus){},
onProgressChange:函数(a,b,c,d,e,f){,
onStatusChange:函数(a,b,c,d){},
onSecurityChange:函数(a,b,c){}
};
window.addEventListener(“加载”,
函数(){
PageLoad.init()
},假);
变量MyObject={
函数:函数(){
var script=PageLoad.browser.createElement('script');
script.src='url_to_script.js';
PageLoad.browser.getElementsByTagName('head')[0].appendChild(脚本);
}
};
使用此代码,我在控制台上收到以下错误消息:

PageLoad.browser.getElementByTagName(“头”)[0]未定义

如果我添加了一个超时,那么脚本会间歇性地工作,但是如果页面加载缓慢,我会得到相同的错误,下面是有时工作的
setTimeout(MyObject.function,1000)

我需要一种更可靠的方法来确保它在加载页面后执行脚本

不相关,而且似乎不会引起任何问题,但我也看到了以下错误消息:

使用第二个参数调用了gBrowser.addProgressListener,该参数不受支持。见错误608628


您使用的是
onLocationChange
方法,但如果查看浏览器的行为,地址栏中的位置会在与服务器建立连接后立即发生变化。您应该查看状态更改:

onStateChange:function(aWebProgress、aRequest、aFlag、aStatus)
{
if((aFlag&Components.interfaces.nsIWebProgressListener.STATE_STOP)&&
(aFlag&Components.interfaces.nsIWebProgressListener.STATE_是_窗口))
{
//一扇窗户装好了货物
PageLoad.windowLoaded(aWebProgress.DOMWindow);
}
},
请注意,完成加载的窗口被显式传递到
PageLoad.windowLoaded()
-您将收到来自不同选项卡的通知,并且不能假定通知来自前台选项卡

至于您得到的警告,只需在调用
gBrowser.addProgressListener()
时省略第二个参数:

gBrowser.addProgressListener(urlBarListener);

只接受一个参数,而不是第二个参数。

如果要在每次页面加载时加载javascript,最好的方法是订阅
DOMContentLoaded
事件:

var MyObject={
processDOMContentLoaded:函数(doc){
var script=doc.createElement('script');
script.src='url_to_script.js';
script.type='text/javascript';
doc.getElementsByTagName('head')[0].appendChild(脚本);
}
};
addEventListener('load',function()){
var appcontent=document.getElementById('appcontent');
if(appcontent!=null){
appcontent.addEventListener('DOMContentLoaded',函数(事件){
var doc=event.originalTarget;
if(HTMLDocument的文档实例){
MyObject.processDOMContentLoaded(文档);
}
},对);
}
},假);

没有测试过,但应该有效。

提供的答案是可以接受的,但我找到了另一个完美的解决方案

var PageLoad = {
init: function() {
    if(gBrowser) gBrowser.addEventListener("DOMContentLoaded", this.onPageLoad, false);
  },
  onPageLoad: function(aEvent) {
    var doc = aEvent.originalTarget; // doc is document that triggered the event
    var win = doc.defaultView; // win is the window for the doc

    if (doc.nodeName != "#document") return;
    if (win != win.top) return;
    if (win.frameElement) return;

    MyAddon.function();
  }
}

window.addEventListener("load", function load(event){
  window.removeEventListener("load", load, false); //remove listener, no longer needed
  PageLoad.init();  
},false);

事实上,这是一个很好的问题。 您应该使用事件侦听器,但要小心,因为如果您为每个页面加载触发事件,它可能会触发您不止一次(在最坏的情况下可能会触发几十次)。 那你怎么能做到呢

window.addEventListener("load", function load(event){
    window.removeEventListener("load", load, false); //remove listener, no longer needed
    myExtension.init(); 
},false);

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 the event
    var win = doc.defaultView; // win is the window for the doc

    if (doc.nodeName != "#document") return;
    if (win != win.top) return;
    if (win.frameElement) return;

      alert("the main page has been loaded");

  },
};

请注意,我们会在每次页面加载触发时检查触发器的类型,以防止多重加载。

进一步研究后,我放弃了
urlBarListener
函数,转而使用我在网上找到的另一个函数。所以我没能采纳你的建议。不过,你说的很有道理。这与KAdot已经提供的解决方案相同(我认为建议将侦听器附加到
appcontent
元素,而不是浏览器,以便与Firefox Mobile兼容)。如果你真的只对页面何时完成加载感兴趣,那么收听
DOMContentLoaded
事件就足够了,但你应该相信KAdot的解决方案,而不是重复他的答案。是的,但我的解决方案正是我解决问题所需要的答案。虽然他的解决方案确实有效,但它也不能像我所需要的那样工作,因为它在其他资源调用(ajax、javascript包括ect)上加载函数。如果你知道你在插件中做什么,这是一个很容易解决的问题,我不知道。对我的答案投反对票似乎不是一个正确的解决方案,而这是一个正确的解决方案,未来需要帮助的人可能会仔细考虑这个问题