【问题标题】:How to trigger action before url in <browser> will be loaded?如何在 <browser> 中的 url 加载之前触发操作?
【发布时间】:2013-11-03 21:00:20
【问题描述】:

我正在尝试在&lt;browser&gt; 元素中加载指定的 url 之前执行一些操作。 &lt;browser&gt; 可以是侧边栏或选项卡。

示例:(上下文为浏览器主窗口):

// 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 可以用于此,但我很困惑我需要等待哪些标志。

【问题讨论】:

    标签: javascript firefox-addon xpcom


    【解决方案1】:

    使用content-document-global-created or document-element-inserted notification of nsIObserverService。您使用哪一个取决于您的脚本在做什么。如果它只是在您的示例中设置窗口级变量,那么 content-document-global-created 将是最好的。如果您需要插入元素或有 &lt;html&gt; 元素可用,则 document-element-inserted 会更好。

    document-element-inserted 是包含@run-at document-start 时的方法that Greasemonkey uses

    【讨论】:

    • 谢谢。 content-document-global-created 有一个限制。它的 location.href may not be final url yet。现在,我正在使用另一种使用进度侦听器的解决方案。
    【解决方案2】:

    我最终使用了这种方法。它是通过反复试验编码的,因此在某些情况下可能会出错,但我没有注意到许多测试有任何问题。

    // 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);
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-13
      • 1970-01-01
      • 1970-01-01
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多