我正在处理用户脚本,但我发现当主页发出AJAX请求时,该脚本未运行。
有什么方法可以在主页加载和AJAX请求上触发用户脚本?
在AJAX请求上重新运行脚本代码的明智方法是,专注于页面的关键部分并检查更改。
例如,假设页面包含如下所示的HTML:
<div id="userBlather"> <div class="comment"> Comment 1... </div> <div class="comment"> Comment 2... </div> ... </div>
并且您希望脚本对每个注释进行处理。
现在,您 可以 拦截所有AJAX调用, 或者侦听DOMSubtreeModified(不建议使用)或使用MutationObservers,但是这些方法可能会变得棘手,挑剔且过于复杂。
DOMSubtreeModified
MutationObserver
在通配页上获取ajax形式的内容的一种更简单,更可靠的方法是使用waitForKeyElements下面的函数对其进行轮询。
waitForKeyElements
例如,此脚本将在AJAX中突出显示包含“啤酒”的注释:
// ==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; }