过去几天我一直在为一个网站开发Chrome Extension。它很顺利,但我遇到了一个你可以帮助的问题。
以下是扩展功能概述(此功能已完成):
我取得了很多进步,但这是我的问题:
当用户访问Twitter时,内容脚本被激活,页面上的所有推文都会获得我的新按钮 - 但如果用户点击“更多...”并动态加载接下来的20条推文...这些新添加到页面DOM不受内容脚本的影响(因为它已经加载)。
我可以在“更多...”按钮中添加一个事件监听器,然后再次触发原始内容脚本(并添加新按钮),但我必须预测twitter的ajax请求响应的长度。 我无法利用他们的Ajax请求,该请求会在请求完成后提取更多推文并调用我的addCurateButton()函数。
您认为最佳解决方案是什么? (如果有的话)
答案 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交互可能是哄骗内容脚本做的最难的事情,但我认为你走的正确。我采取了几种不同的方法来解决这个问题。但是,在你的情况下,我认为这两种方法的组合(我将在最后解释)是最好的。
将事件侦听器附加到DOM以检测相关更改。这个解决方案就是你所建议的,并介绍了竞争条件。
连续检查DOM以查找循环内部的更改(最好是使用setInterval
执行的更改)。这种解决方案是有效的,但效率相对较低。
两全其美的方法是仅在按下更多按钮后启动检查循环。这个解决方案既可以避免时间问题,又可以提高效率。
答案 2 :(得分:0)
您可以在按钮上附加事件处理程序,或者用于获取更多结果的链接。然后附加一个函数,这样无论何时单击按钮,您的扩展都会从DOM中删除所有按钮并重新插入它们,或者检查天气中您的按钮是否存在于该特定DOM元素类中,如果没有,则附加一个按钮“T