Javascript 在 AJAX 请求上触发 Greasemonkey 脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8281441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fire Greasemonkey script on AJAX request
提问by LooPer
I am working on a user script and I've just found that the script is not run when the main page makes AJAX requests.
我正在处理一个用户脚本,我刚刚发现当主页发出 AJAX 请求时脚本没有运行。
Is there any way to fire the user script both on main page load and on AJAX requests?
有没有办法在主页加载和 AJAX 请求上触发用户脚本?
回答by Brock Adams
The smart way to rerun the script's code on AJAX requests, is to focus on the key bits of the page and check for changes.
在 AJAX 请求上重新运行脚本代码的聪明方法是关注页面的关键部分并检查更改。
For example, suppose a page contained HTML like so:
例如,假设一个页面包含这样的 HTML:
<div id="userBlather">
<div class="comment"> Comment 1... </div>
<div class="comment"> Comment 2... </div>
...
</div>
and you wanted the script to do something with each comment as it came in.
并且您希望脚本在每条评论进来时对其进行处理。
Now you couldintercept all AJAX calls, or listen for (deprecated), or use DOMSubtreeModified
MutationObserver
s, but these methods can get tricky, finicky, and overly complicated.
现在,您可以拦截所有 AJAX 调用,或侦听(已弃用)或使用DOMSubtreeModified
MutationObserver
s,但这些方法可能会变得棘手、挑剔且过于复杂。
A simpler, more robust way to get ajax-ified content on a wild page is to poll for it using something like the waitForKeyElements
function, below.
在一个野生页面上获取 ajax 化内容的一种更简单、更健壮的方法是使用类似waitForKeyElements
下面的函数来轮询它。
For example, this script will highlight comments that contain "beer", as they AJAX-in:
例如,此脚本将突出显示包含“beer”的注释,因为它们是 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;
}
Update:
更新:
For convenience, waitForKeyElements()
is now hosted on GitHub.
为方便起见,waitForKeyElements()
现托管在 GitHub 上。
This answershows an example of how to use the hosted function.
回答by Mr-IDE
Another way — simpler and smaller but less flexible — is to use a JavaScript time delay to wait for the AJAX/jQuery to load and finish. For example, if the following HTML was dynamically generated after first load:
另一种更简单、更小但不太灵活的方法是使用 JavaScript 时间延迟来等待 AJAX/jQuery 加载和完成。例如,如果以下 HTML 是在首次加载后动态生成的:
<div id="userBlather">
<div class="comment"> Comment 1... </div>
<div class="comment"> Comment 2... </div>
...
</div>
Then a greasemonkey script like this would be able to modify it:
然后像这样的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;
}
}
See guidance here: Sleep/Pause/Wait in Javascript
请参阅此处的指南:Javascript 中的睡眠/暂停/等待