动态页面的用户脚本?

时间:2015-11-18 08:43:34

标签: javascript jquery greasemonkey userscripts

我写了很多小的GreaseMonkey UserScripts,通常都是为了我自己。即使他们完成了自己的工作,也有一个小问题我无法理解:

如何处理动态变化的网站?

例如,亚马逊等网络商店在点击“下一页”时不再直接重新加载所有内容,而只是动态更新实际条目。我有一个脚本来突出显示一些内容,但每次切换到新页面时我都必须F5整个页面。

现在我通过 onclick 事件执行此操作,然后在重新应用脚本之前超时3秒,但我觉得它相当“脏”。有没有更清洁的方法?

1 个答案:

答案 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);
}