Fire AJAX请求上的Greasemonkey脚本
我正在处理一个用户脚本,我刚刚发现,当主页面发出AJAX请求时脚本没有运行。
有什么办法在主页面加载和AJAX请求上触发用户脚本?
在AJAX请求上重新运行脚本代码的智能方法是关注页面的关键位并检查更改。
例如,假设页面包含HTML,如下所示:
<div id="userBlather"> <div class="comment"> Comment 1... </div> <div class="comment"> Comment 2... </div> ... </div>
而且你希望脚本能够在每个评论进行时做一些事情。
现在你可以拦截所有的AJAX调用, 或者侦听 (不build议使用),或者使用DOMSubtreeModified
MutationObserver
,但是这些方法可能会变得棘手,挑剔和过于复杂。
在wild页面上获取ajax-ified内容的一个更简单,更健壮的方法是使用类似下面的waitForKeyElements
函数来轮询它。
例如,此脚本将突出显示包含“beer”的注释,因为它们是AJAX-in:
// ==UserScript== // @name _Refire on key Ajax changes // @include http://YOUR_SITE.com/YOUR_PATH/* // @require http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js // ==/UserScript== function highlightGoodComments (jNode) { //***** YOUR CODE HERE ***** if (/beer/i.test (jNode.text () ) ) { jNode.css ("background", "yellow"); } //... } waitForKeyElements ("#userBlather div.comment", highlightGoodComments); /*--- waitForKeyElements(): A utility function, for Greasemonkey scripts, that detects and handles AJAXed content. IMPORTANT: This function requires your script to have loaded jQuery. */ function waitForKeyElements ( selectorTxt, /* Required: The jQuery selector string that specifies the desired element(s). */ actionFunction, /* Required: The code to run when elements are found. It is passed a jNode to the matched element. */ bWaitOnce, /* Optional: If false, will continue to scan for new elements even after the first match is found. */ iframeSelector /* Optional: If set, identifies the iframe to search. */ ) { var targetNodes, btargetsFound; if (typeof iframeSelector == "undefined") targetNodes = $(selectorTxt); else targetNodes = $(iframeSelector).contents () .find (selectorTxt); if (targetNodes && targetNodes.length > 0) { btargetsFound = true; /*--- Found target node(s). Go through each and act if they are new. */ targetNodes.each ( function () { var jThis = $(this); var alreadyFound = jThis.data ('alreadyFound') || false; if (!alreadyFound) { //--- Call the payload function. var cancelFound = actionFunction (jThis); if (cancelFound) btargetsFound = false; else jThis.data ('alreadyFound', true); } } ); } else { btargetsFound = false; } //--- Get the timer-control variable for this selector. var controlObj = waitForKeyElements.controlObj || {}; var controlKey = selectorTxt.replace (/[^\w]/g, "_"); var timeControl = controlObj [controlKey]; //--- Now set or clear the timer as appropriate. if (btargetsFound && bWaitOnce && timeControl) { //--- The only condition where we need to clear the timer. clearInterval (timeControl); delete controlObj [controlKey] } else { //--- Set a timer, if needed. if ( ! timeControl) { timeControl = setInterval ( function () { waitForKeyElements ( selectorTxt, actionFunction, bWaitOnce, iframeSelector ); }, 300 ); controlObj [controlKey] = timeControl; } } waitForKeyElements.controlObj = controlObj; }
更新:
为了方便, waitForKeyElements()
现在托pipe在GitHub上 。
这个答案显示了一个如何使用托pipe函数的例子 。
另一种方式 – 更简单,更小但更不灵活 – 是使用JavaScript时间延迟来等待AJAX / jQuery加载和完成。 例如,如果在第一次加载之后dynamic生成以下HTML:
<div id="userBlather"> <div class="comment"> Comment 1... </div> <div class="comment"> Comment 2... </div> ... </div>
然后像这样的一个greasemonkey脚本将能够修改它:
// Wait 2 seconds for the jQuery/AJAX to finish and then modify the HTML DOM window.setTimeout(updateHTML, 2000); function updateHTML() { var comments = document.getElementsByClassName("comment"); for (i = 0; i < comments.length; i++) { comments[i].innerHTML = "Modified comment " + i; } }
在这里看到指导: 睡眠/暂停/在Javascript中等待