2010-07-21 96 views
1

过去几天我一直在为Chrome网站工作。它的出现非常好,但我遇到了一个问题,您可能会提供帮助。Google Chrome浏览器扩展程序 - 如何多次包含内容脚本?

这里的扩展做什么大纲(此功能齐全):

  1. ,用户可以输入自己的用户名和密码进入扩展弹出 - 并验证他们的用户帐户关于特定网站
  2. 当用户浏览http://twitter.com时,会动态包含一个内容脚本,该脚本会操纵DOM,以在显示的每条推文旁包含一个额外的按钮。
  3. 当用户点击这个按钮,他们都带有一个对话框

我已经取得了很大的进步,但这里是我的问题:

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

我可以添加一个事件监听器到'More ...'按钮,然后再触发原始内容脚本(并添加新的按钮),但我将不得不预测twitter的ajax请求响应的长度。 一旦请求完成,我就无法进入他们的Ajax请求,这个请求会提取更多的推文并调用我的addCurateButton()函数。

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

回答

0

与Ajax交互可能是哄一个内容脚本最难的事情,但我认为你是在正确的轨道上。我已经采取了几种不同的方法来解决这个问题。不过,就你而言,我认为两种方法的组合(我将在后面解释)将是最好的。

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

  2. 不断检查DOM是否从循环内部发生变化(最好使用setInterval执行一次)。这个解决方案将是有效的,但效率相对较低。

最佳的两个-世界的方法是启动按钮被按下后,才检查循环。这种解决方案既可以避免时间问题,又可以提高效率。

3

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

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

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 == true,然后中止注入,以免同时过多地执行注入。

0

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

相关问题