【问题标题】:Is there a FF equivalent to chrome.declarativeContent.onPageChanged?是否有相当于 chrome.declarativeContent.onPageChanged 的​​ FF?
【发布时间】:2017-01-08 04:59:26
【问题描述】:

我正在将 Chrome 扩展程序移植到 Firefox WebExtensions,但我一直在为 chrome.declarativeContent.onPageChanged 寻找解决方法。

我的 FF Webextension 包含在某些网站上导航时必须显示的页面操作。但是,可用 API 中的所有侦听器似乎都不允许这样做。

我特别尝试过:

chrome.runtime.onInstalled.addListener(onChange);
chrome.tabs.onCreated.addListener(onChange);
chrome.tabs.onActivated.addListener(onChange);
chrome.tabs.onUpdated.addListener(onChange);
chrome.webNavigation.onDOMContentLoaded(onChange);
chrome.webNavigation.onCreatedNavigationTarget(onChange);

是否有任何已知的解决方法?

【问题讨论】:

    标签: javascript google-chrome-extension firefox-addon-webextensions


    【解决方案1】:

    您必须手动显示 pageAction,因为 declarativeContent API 是 not yet supported

    chrome.pageAction.show(tabId);
    chrome.pageAction.hide(tabId);
    

    如果规则是基于 URL 匹配的,那么实现非常简单:

    chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
        if (changeInfo.status === 'complete' && tab.url.match(/something/)) {
            chrome.pageAction.show(tabId);
        } else {
            chrome.pageAction.hide(tabId);
        }
    });
    

    但是,如果它是基于 DOM 元素的,则必须使用 content script

    chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
        if (changeInfo.status === 'complete' && tab.url.match(/something/)) {
            chrome.tabs.executeScript(tabId, {
                code: 'document.querySelector(' + JSON.stringify(someSelector) + ')'
            }, function(results) {
                if (results[0]) {
                    chrome.pageAction.show(tabId);
                } else {
                    chrome.pageAction.hide(tabId);
                }
            });
        } else {
            chrome.pageAction.hide(tabId);
        }
    });
    

    这是一个非常简化的代码。可以增强它以在页面加载时查找元素。

    【讨论】:

    • 如果是基于内容脚本的方法,onUpdated 甚至可能不需要监听器。
    • chrome.tabs.onUpdated.addListener 在我导航到不同的站点时有效,但在我第一次打开选项卡时无效。将在下面发布我的解决方法!
    • 仅供参考:您的代码将在大多数页面上多次注入和执行内容脚本。 tabs.onUpdated 事件通常在每次页面加载时触发多次,tab.status === 'complete'(一个错误 IMO)。可能:查找changeInfo.url && changeInfo.status==='complete'。有关可用事件的更详细信息,请参阅tabs.onUpdated.addListener's changeInfo.status goes from undefined to Complete without ever going to loading。该答案中的代码可以帮助调查可用的事件并确定适用于这种情况的标准。
    • 正确。但有时,一旦元素从页面中消失,页面操作应该被隐藏,多次执行并没有什么问题。尽管在这种情况下, MutationObserver 或 setInterval 回调似乎是更好的选择。其实我本来打算用changeInfo.status,所以谢谢,答案已经更新了。
    • 这里代码的简单情况(执行&终止),多次执行是可以的。人们在多次注入未完全终止的东西时会遇到问题。是的,对于chrome.declarativeContent 中的 CSS 选择器,除了将常驻内容脚本注入到与 URL 匹配的每个页面(更简单?使用 manifest.json "content_scripts") 使用 MutationObserver 或 setTimeout 然后在匹配时向后台脚本发送消息。毕竟,chrome.declarativeContent 是这样做的捷径。
    【解决方案2】:

    对于简单的 URL 匹配、新标签页以及对现有标签页的更改,此方法有效:

    • 在清单中包含tabs 权限。

    .

    chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
      if (changeInfo.status === 'complete' && tab.url.match(/something/)) {
        chrome.pageAction.show(tabId);
      } else if (changeInfo.status === 'complete') {
        chrome.pageAction.hide(tabId);
      }
    });
    chrome.tabs.onCreated.addListener(function(tab) {
      if (tab.url && tab.url.match(/something/)) {
        chrome.pageAction.show(tab.id);
      } else if (tab.url) {
        chrome.pageAction.hide(tab.id);
      }
    });
    

    【讨论】:

      【解决方案3】:

      迄今为止最好的等价物似乎是:

      var target = "<all_urls>";
      chrome.webRequest.onCompleted.addListener(onChange, {urls: [target]});
      

      onChange() 包括将当前 URL 与正则表达式匹配,然后是 chrome.pageAction.show(tabInfo.id);

      【讨论】:

      • 它将触发所有类型的网络请求,包括图像、脚本和样式。使用过滤将其限制在仅主框架:chrome.webRequest.onCompleted.addListener(onChange, {urls: [target], types: ['main_frame']});
      猜你喜欢
      • 2010-10-16
      • 2023-04-04
      • 2016-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多