【问题标题】:Chrome Extension: How to reload/re-execute content script on Ajax requestChrome 扩展:如何根据 Ajax 请求重新加载/重新执行内容脚本
【发布时间】:2011-09-06 20:23:03
【问题描述】:

我正在尝试为某个网站执行内容脚本(注入按钮或更改链接),但是我想在用户浏览网站时执行此操作。

问题是网页是在用户浏览时使用 ajax 请求动态构建的。

我之前在我编写的扩展程序中通过将我的 JavaScript 实际注入网页中解决了这个问题。

我想知道是否有更好的选择,而不是在我的内容脚本中注册一个 ajaxComplete 事件或类似的东西,以便我可以重新执行。

我可以做到以下几点:

function listener()
{
    console.debug("listener fired.");
}
document.addEventListener("DOMSubtreeModified", listener, false);

但是在一个页面加载过程中触发的次数太多了。

【问题讨论】:

  • 如果网站使用哈希 (#...) 或新的 HTML5 历史 API,则需要查找某些事件(onhashchangeonpopstate)。
  • 他们不是。供参考的网站是beatport
  • 在 Chrome 上,我可以看到 URL 发生了变化,而页面没有离开。我怀疑他们确实使用了历史 API。他们在源代码中使用history.pushState
  • 如何查找这些事件?我不怎么做JS
  • @pimvdb:他们只是在第一次加载时推送一次状态。导致 URL 更改的每次点击都不会触发额外的推送

标签: javascript ajax google-chrome-extension dom-events


【解决方案1】:

据我所知,没有 ajax 监听器,但它无济于事,因为您需要在页面被修改时捕获,而不是 ajax 请求被发送/接收(页面修改通常发生在以后并且不能被绑定ajax 请求)。

DOMSubtreeModified 是正确的方法,只需对过于频繁的调用实施一些保护即可:

function listener()
{
    console.debug("listener fired.");
}

var timeout = null;
document.addEventListener("DOMSubtreeModified", function() {
    if(timeout) {
        clearTimeout(timeout);
    }
    timeout = setTimeout(listener, 500);
}, false);

这样,如果 500 毫秒内没有其他事件,它将触发 listener

【讨论】:

  • 我试过上面的代码。有用!但是对于我对页面所做的每一次更改,侦听器都会被触发,因此它变成了一种无限循环。有什么建议吗?
  • 我也遇到了这个问题。它永远不会停止。
【解决方案2】:

我发现的最佳答案有点有趣,并且在内容脚本和 background.html 文件之间包含了一些 message passing

我会发布代码然后解释:

Background.html

  function updatePageAction(tabId)
  {
    chrome.tabs.sendRequest(tabId, {is_content_script: true}, function(response) {
      if (response.is_content_script)
        chrome.pageAction.show(tabId);
    });
  };

  chrome.tabs.onUpdated.addListener(function(tabId, change, tab) {
    if (change.status == "complete") {
      updatePageAction(tabId);
    }
  });

content_script.js

// The background page is asking us to find an address on the page.
if (window == top) {
  chrome.extension.onRequest.addListener(function(req, sender, sendResponse) {
        if (req.is_content_script)
            start_content_script();
            sendResponse({is_content_script: true});
  });
};

您想解决在 DOM 更改时更新或重新执行脚本的问题。幸运的是,DOM 更改涉及 URL 更改(尽管是 AJAX DOM 更改来更新页面)。 但是,URL 更改会触发 onUpdated 事件。然而,每个选项卡都会触发这些“事件”,我们希望确保我们只关心与我们的内容脚本匹配的那个(您可以在清单中指定匹配!)。

通过将消息传递给当前选项卡中正在执行的 content_script,我们在询问“你是我的内容脚本吗?如果是,请重新启动。”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 2013-06-01
    • 2014-03-04
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多