-
Star
(277)
You must be signed in to star a gist -
Fork
(156)
You must be signed in to fork a gist
-
-
Save BrockA/2625891 to your computer and use it in GitHub Desktop.
/*--- waitForKeyElements(): A utility function, for Greasemonkey scripts, | |
that detects and handles AJAXed content. | |
Usage example: | |
waitForKeyElements ( | |
"div.comments" | |
, commentCallbackFunction | |
); | |
//--- Page-specific function to do what we want when the node is found. | |
function commentCallbackFunction (jNode) { | |
jNode.text ("This comment changed by waitForKeyElements()."); | |
} | |
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; | |
} |
No one's bothered to link the mystical rumored fork that uses MutationObserver so here's the link: https://gist.github.com/double-beep/c4d4ec3866e5e54ae514c0aab60af242
Thanks, it's interesting to compare the two approaches. Maybe this is out of the scope of this page, but...what would be the advantage of using this script over Mutation Observer (and vice versa)?
For a modern dynamic webpage, you normally wouldn't want to naively attach a MutationObserver
to the root of the document body (e.g., try it on YouTube, and the page will slow to a crawl due to callback thrashing). It's better to poll for a specific container/parent element, and when it is found, stop polling and start listening for its child elements. I prefer to use ViolentMonkey's VM.observe()
which wraps MutationObserver
in a simpler syntax for userscripts. Here is an example usage: Turn rumble comment timestamps into clickable links (here I'm using GM_wrench.wait()
for more general purpose polling, not WFKE)
No one's bothered to link the mystical rumored fork that uses MutationObserver so here's the link: https://gist.github.com/double-beep/c4d4ec3866e5e54ae514c0aab60af242
Thanks, it's interesting to compare the two approaches. Maybe this is out of the scope of this page, but...what would be the advantage of using this script over Mutation Observer (and vice versa)?
Properly implemented, MutationObserver is now faster, more efficient, and more responsive. I do not think that linked script is the best example and it is not as flexible or robust as this WFKE. Nor is it a drop-in replacement. But if it, or any of the thousands of now available alternatives, works for you, then awesome. ;)
To be fair to me, this WFKE was written before MutationObserver was widely available and while it was particularly buggy and resource intensive. It performs well enough that I almost never need anything else and haven't felt a pressing need to refactor it yet.
No one's bothered to link the mystical rumored fork that uses MutationObserver so here's the link: https://gist.github.com/double-beep/c4d4ec3866e5e54ae514c0aab60af242