我写了很多小的GreaseMonkey UserScripts,通常都是为了我自己。即使他们完成了自己的工作,也有一个小问题我无法理解:
如何处理动态变化的网站?
例如,亚马逊等网络商店在点击“下一页”时不再直接重新加载所有内容,而只是动态更新实际条目。我有一个脚本来突出显示一些内容,但每次切换到新页面时我都必须F5整个页面。
现在我通过 onclick 事件执行此操作,然后在重新应用脚本之前超时3秒,但我觉得它相当“脏”。有没有更清洁的方法?
答案 0 :(得分:0)
下面的答案是弃用。您应该使用Use MutationObserver或setInterval。请参阅:Greasemonkey script to work on dynamically loaded posts on Facebook
由于您使用的是Firefox,因此可以触发DOMSubtreeModified
事件。
为此,首先将当前脚本的代码部分包装在函数中;例如:
// ==UserScript==
// @name
// ==/UserScript==
function LocalMain ()
{
//--- Do all of your actions here.
}
LocalMain (); //-- Fire GM script once, normally.
接下来,单击“下一页”时,查找DOM节点已更改。一旦确定了正确的节点,就可以设置事件监听器。但是,您还需要一个短暂的时间延迟,因为节点一次变化数百个,您需要等到当前批次完成。
所以,把它们放在一起,代码看起来像这样:
if (window.top != window.self) //don't run on frames or iframes
return;
function LocalMain ()
{
//--- Do all of your actions here.
}
LocalMain (); //-- Fire GM script once, normally.
var ContentChangedByAJAX_Timer = '';
//--- Change this next line to find the correct element; sample shown.
var ContentWrapperNode = document.getElementById ('THE ID OF DOM NODE GOT UPDATE WHEN CLICKING ON NEXT PAGE');
ContentWrapperNode.addEventListener ("DOMSubtreeModified", PageBitHasLoaded, false);
function PageBitHasLoaded (zEvent)
{
/*--- Set and reset a timer so that we run our code (LocalMain() ) only
AFTER the last post -- in a batch -- is added. Adjust the time if needed, e.g. 3 seconds.
*/
if (typeof ContentChangedByAJAX_Timer == "number")
{
clearTimeout (ContentChangedByAJAX_Timer);
ContentChangedByAJAX_Timer = '';
}
ContentChangedByAJAX_Timer = setTimeout (function() {LocalMain (); }, 3000);
}