Firefox插件SDK/tabs:"ready"事件在所有页面加载时都不触发?

3

我正在使用sdk/tabs监听页面加载:

require('sdk/tabs').on('ready', function(tab) { console.log(tab.url); } );

在正常导航期间,它按预期工作,但在一些具有脚本导航的页面上,“ready”事件不会触发。例如,加载Flickr照片页面:

https://www.flickr.com/photos/42559357@N04/14696401803

使用GUI导航(侧边的箭头或底部的图标)浏览其他照片。选项卡URL会更改,但监听器从未被调用。

这是正常现象吗?有没有办法跟踪此类页面加载?

预计时间:我注意到sdk/context-menu没有遇到同样的问题,这给了我一个解决方法的想法:

var cm = require("sdk/context-menu");
cm.Item({
    label: "dummy",
    contentScript: 'self.on("context", function (node) {' +
        '  self.postMessage(document.URL);' +
        '  return false;' +
    '});',
    onMessage: function (pageUrl) {
        console.log(pageUrl);
    }
});

每当在页面上打开上下文菜单时,都会触发onMessage下的函数,并且像上面描述的棘手的页面更改不会使脚本混乱:它将准确记录当前URL。

恰好,我正在针对页面URL定制上下文菜单,所以这可能适合我(我将添加URL过滤和一种方法来确保有效载荷仅在每个页面上交付一次)。但我仍然希望回答原始问题。

ETA2:page-mod与选项卡具有相同的问题:以下内容将侦听Flickr上新页面的打开,但不会在通过Flickr UI加载新页面时进行侦听:

var pageMod = require("sdk/page-mod");
pageMod.PageMod({
    include: '*.flickr.com',
    contentScriptWhen: 'start',
    contentScript: 'self.port.emit("pageOpened", document.URL);',
    onAttach: function(worker) {
        worker.port.on("pageOpened", function(pageUrl) {
            console.log(pageUrl);
        });
    }
});
3个回答

2

我曾遇到过这个问题。原因是Firefox“预加载”了页面,所以加载时带有state="ready"状态。因此没有页面状态改变,事件也没有被触发。 为了解决这个问题,我监听了“open”事件(tabs.on("open", ...)),并检查页面是否处于“ready”状态:

tabs.on("open", function (tab) {
    tab.on("pageshow", doSomething);
    if (tab.readyState == "complete") {
        doSomething(tab);
    }
});

1

谢谢您的建议,但是pageshow对问题没有影响。我想强调一下,在我的Flickr示例中,UI实际上会更改位置URL,而不仅仅是内容。因此,这应该是触发“ready”和“pageshow”的东西,但它并没有。 - Dmitry E.
1
不需要在文档没有真正重新加载时触发ready和pageshow。可以使用history api更改URL。有关历史记录API的更多信息,请参见此答案 - therealjeffg
文档正在实际加载;新文档,不是从历史记录中获取的。但是没有任何通常的事件触发。DOMContentLoaded在内容脚本中不会触发。我能够捕获的唯一事件是DOMSubtreeModified,但它每次页面加载都会多次触发,因此不是非常方便或高效的。 - Dmitry E.
1
它没有加载新文档(在Flickr上,您建议的示例)。如果您查看开发人员工具中的Firefox网络监视器,按HTML请求过滤,然后单击照片,您将看到的唯一页面加载是“beacon”指标ping。 - therealjeffg
1
嗯,你是对的:它似乎使用 API 请求就地构建新页面。它确实以某种方式更改了选项卡、窗口等的 URL。除非我可以专门监听到这一点,否则我想最简单的解决方案是毕竟听取DOMSubtreeModified。我宁愿不要等到上下文菜单弹出,因为那样插件可能无法在用户看到结果之前完成其工作。 - Dmitry E.
@DmitryE.:正如canuckstani所指出的那样,可以使用history.pushState更改URL:https://developer.mozilla.org/en-US/docs/Web/API/History_API#The_pushState%28%29_method。使用DOMSubtreeModified比轮询要好得多。 - serv-inc

0

两年后,Firefox将停止支持旧的插件平台,并强制所有人切换到WebExtensions。但对于我的Flickr插件来说,这实际上是一种福音,因为现在我可以通过监听背景脚本中选项卡URL的更改来做我想做的事情:

chrome.tabs.onUpdated.addListener(onTabChange)

function onTabChange(tabId, changeInfo) {
  if (changeInfo.url) {
    // do stuff
  }
}

这确实可以与Flickr的页面更新一起使用。


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