如何检查当前浏览器选项卡的URL是否已更改?

3

我需要在我的Firefox扩展程序中使用它。

我已经尝试过window.onload事件监听器,并检查当前url == 旧url,这是一个好主意,但当页面加载PDF时它不起作用。

我也看到了哈希变化的函数,但它只适用于Firefox 3.6;我需要它至少能在Firefox 3上工作。

因此,我需要一个事件监听器来检查document.location是否发生变化。

2个回答

3

添加进度监听器,并在选项卡内监控位置变化。使用Addon SDK覆盖选项卡切换。

要安装监听器,使用viewFor将SDK选项卡转换为其原始(旧)表示形式。使用modelFor和getTabForContentWindow进行反向转换。

const tabs = require("sdk/tabs");
const {viewFor} = require('sdk/view/core');
const {modelFor} = require('sdk/model/core');
const {getBrowserForTab, getTabForContentWindow} = require("sdk/tabs/utils");
const {Ci, Cu} = require("chrome");
Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);

var progressListener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]),
    onLocationChange: function(aProgress, aRequest, aURI) {
        var highLevel= modelFor(getTabForContentWindow(aProgress.DOMWindow));
        console.log("onLocationChange ", highLevel.url);
    }
};

tabs.on('open', function(newTab) {
    var lowLevel = viewFor(newTab);
    var browser = getBrowserForTab(lowLevel);
    browser.addProgressListener(progressListener);
});

转换为Chrome窗口的启发。


3
例如,您可以使用:
var mainWindow = window
    .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
    .getInterface(Components.interfaces.nsIWebNavigation)
    .QueryInterface(Components.interfaces.nsIDocShellTreeItem).rootTreeItem
    .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
    .getInterface(Components.interfaces.nsIDOMWindow);

mainWindow.getBrowser().addEventListener("DOMContentLoaded",
                        your_function, false);

但是,重点是需要将监听器添加到浏览器而不是窗口。
编辑 请参阅https://developer.mozilla.org/En/Code_snippets/Tabbed_browser以获取有关从不同上下文访问浏览器以及其他一些有用信息的信息。
编辑 只是为了增加一些细节...
function your_function(event) {
    if (event.originalTarget instanceof HTMLDocument) {
    var doc = event.originalTarget;
        // if it's just a frame element, then return and wait for the
        // main event to fire.
        if (event.originalTarget.defaultView.frameElement)
             return;

        // now you can use doc.location however you want
    }
}

请注意,这将响应在任何标签页中打开的页面,而不是特定的标签页。
对于特定的选项卡,您可以使用以下内容:
var newTabBrowser = gBrowser.getBrowserForTab(gBrowser.addTab("http://www.google.com/"));
newTabBrowser.addEventListener("load", function () {
    newTabBrowser.contentDocument.body.innerHTML = "<div>hello world</div>";
}, true);

上面的代码添加了一个新的标签页,并添加了一个监听器。然而,对于所有的标签页,您需要像下面这样做。然后在每个添加的标签页上添加“DOMContentLoaded”事件侦听器(并在关闭时删除)。
您可能还想查看:https://developer.mozilla.org/En/Code_snippets/Tabbed_browser#Notification_when_a_tab_is_added_or_removedhttps://developer.mozilla.org/En/Code_snippets/Tabbed_browser#Getting_document_of_currently_selected_tab (为了保留)
function exampleTabAdded(event) {
  var browser = gBrowser.getBrowserForTab(event.target);
  // browser is the XUL element of the browser that's been added
}

function exampleTabMoved(event) {
  var browser = gBrowser.getBrowserForTab(event.target);
  // browser is the XUL element of the browser that's been moved
}

function exampleTabRemoved(event) {
  var browser = gBrowser.getBrowserForTab(event.target);
  // browser is the XUL element of the browser that's been removed
}

// During initialisation
var container = gBrowser.tabContainer;
container.addEventListener("TabOpen", exampleTabAdded, false);
container.addEventListener("TabMove", exampleTabMoved, false);
container.addEventListener("TabClose", exampleTabRemoved, false);

// When no longer needed
container.removeEventListener("TabOpen", exampleTabAdded, false);
container.removeEventListener("TabMove", exampleTabMoved, false);
container.removeEventListener("TabClose", exampleTabRemoved, false);

这应该可以让你完成99%的工作。


谢谢Jonathan。你编写的函数似乎是正确的,但问题在于当我加载PDF时,DOMContentLoaded事件不会触发,因此代码也无法执行。最好的解决方案应该是向浏览器的某个控制URL的元素添加一个事件监听器,但我不知道如何实现。 - Manuel Bitto
1
DOMContentLoaded事件仅在具有DOM的MIME类型(例如HTML或XUL)上触发。您是否特别想监听PDF加载?从特定域?您可能需要查看https://developer.mozilla.org/en/Observer_Notifications,具体地是`http-on-examine-response`。还可以参见http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/,以了解观察者通知处理示例。 - Jonathan Fingland
谢谢Jonathan,你让我找到了正确的方向。 现在使用http-on-examine-response,我可以从页面请求中获取事件并检查页面的URL是否已更改,当然它也适用于PDF。但是我还必须检查历史记录的前进和后退,因为它们不会发出HTTP请求。 真的没有其他方法可以仅检查页面请求事件吗?例如,当我在Firefox导航栏中输入网址并按Enter时应该触发的事件? - Manuel Bitto
1
没有问题。您可能想要安装ChromeBug(类似于Firefox的Firebug)以便更轻松地确定如何监听地址栏上的事件。如果您想要监听来自多个来源的请求(书签、链接、地址栏等),那么您将需要观察者通知。您可能需要研究on-modify-request,因为它在请求发送时被触发(不像on-examine-response)。 - Jonathan Fingland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接