Google Chrome扩展程序 - 如何多次包含内容脚本?

时间:2010-07-21 13:15:26

标签: ajax google-chrome google-chrome-extension

过去几天我一直在为一个网站开发Chrome Extension。它很顺利,但我遇到了一个你可以帮助的问题。

以下是扩展功能概述(此功能已完成):

  1. 用户可以在扩展程序弹出框中输入用户名和密码,并验证其特定网站的用户帐户
  2. 当用户浏览http://twitter.com时,会动态包含内容脚本,该内容脚本操纵DOM以在显示的每条推文旁边添加一个额外按钮。
  3. 当用户点击此按钮时,会显示一个对话框
  4. 我取得了很多进步,但这是我的问题:

    当用户访问Twitter时,内容脚本被激活,页面上的所有推文都会获得我的新按钮 - 但如果用户点击“更多...”并动态加载接下来的20条推文...这些新添加到页面DOM不受内容脚本的影响(因为它已经加载)。

    我可以在“更多...”按钮中添加一个事件监听器,然后再次触发原始内容脚本(并添加新按钮),但我必须预测twitter的ajax请求响应的长度。 我无法利用他们的Ajax请求,该请求会在请求完成后提取更多推文并调用我的addCurateButton()函数。

    您认为最佳解决方案是什么? (如果有的话)

3 个答案:

答案 0 :(得分:3)

您要做的是每次更改DOM时重新执行内容脚本。幸运的是,有一个事件。 Have a look at the mutation event called DOMNodeInserted

重写您的内容脚本,以便它将事件侦听器附加到DOM的DOMNodeInserted事件的DOM主体。请参阅以下示例:

var isActive = false;
/* Your function that injects your buttons */
var inject = function() {
  if (isActive) {
    console.log('INFO: Injection already active');
    return;
  }
  try {
    isActive = true;
    //inject your buttons here
    //for the sake of the example I just put an alert here.
    alert("Hello. The DOM just changed.");
  } catch(e) {
    console.error("ERROR: " + e.toString());
  } finally {
    isActive = false;
  }
};
document.body.addEventListener("DOMNodeInserted", inject, false);

最后一行将添加事件侦听器。当页面加载时,事件经常被触发,所以你应该定义一个布尔值(例如var isActive),你初始化为false。每当执行注入函数时,检查isActive ==是否为真,然后中止注入以不同时执行注入。

答案 1 :(得分:0)

与Ajax交互可能是哄骗内容脚本做的最难的事情,但我认为你走的正确。我采取了几种不同的方法来解决这个问题。但是,在你的情况下,我认为这两种方法的组合(我将在最后解释)是最好的。

  1. 将事件侦听器附加到DOM以检测相关更改。这个解决方案就是你所建议的,并介绍了竞争条件。

  2. 连续检查DOM以查找循环内部的更改(最好是使用setInterval执行的更改)。这种解决方案是有效的,但效率相对较低。

  3. 两全其美的方法是仅在按下更多按钮后启动检查循环。这个解决方案既可以避免时间问题,又可以提高效率。

答案 2 :(得分:0)

您可以在按钮上附加事件处理程序,或者用于获取更多结果的链接。然后附加一个函数,这样无论何时单击按钮,您的扩展都会从DOM中删除所有按钮并重新插入它们,或者检查天气中您的按钮是否存在于该特定DOM元素类中,如果没有,则附加一个按钮“T