Skip to content

Instantly share code, notes, and snippets.

@adamhotep
Forked from BrockA/waitForKeyElements.js
Last active August 29, 2025 15:59
Show Gist options
  • Select an option

  • Save adamhotep/7c9068f2196326ab79145ae308b68f9e to your computer and use it in GitHub Desktop.

Select an option

Save adamhotep/7c9068f2196326ab79145ae308b68f9e to your computer and use it in GitHub Desktop.
A utility function, for userscripts including Greasemonkey, that detects and handles AJAXed content.
/*--- waitForKeyElements(): A utility function, for Greasemonkey scripts,
that detects and handles AJAXed content.
Original: https://gist.github.com/BrockA/2625891
Non-jQuery version by: Adam Katz,
https://gist.github.com/adamhotep/7c9068f2196326ab79145ae308b68f9e
License: CC BY-NC-SA 4.0 (*not* GPL-compatible)
changes made by Adam Katz (tracked by adamhotep's github gist) are
also licensed GPL v2+ (but note the CC BY-NC-SA prevents commercial use)
License via https://gist.github.com/BrockA/2625891#gistcomment-1617026
Usage example:
// ==UserScript==
// …
// @require https://git.io/waitForKeyElements.js
// ==/UserScript==
waitForKeyElements (
"div.comments",
commentCallbackFunction
);
//--- Page-specific function to do what we want when the node is found.
function commentCallbackFunction (elem) {
elem.innerHTML = "This comment changed by waitForKeyElements().";
}
*/
function waitForKeyElements (
selectorTxt, /* Required: The querySelector string that
specifies the desired element(s).
*/
actionFunction, /* Required: The code to run when elements are
found. It is passed 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;
//--- Additionally avoid what we've found
var selectorClean = selectorTxt.replace(/(,)|$/g, ":not([wfke_found])$1");
if (typeof iframeSelector == "undefined")
targetNodes = document.querySelectorAll(selectorClean);
else {
targetNodes = [];
var iframe = document.querySelectorAll(iframeSelector);
for (var i = 0, il = iframe.length; i < il; i++) {
var nodes = iframe[i].contentDocument.querySelectorAll(selectorClean);
if (nodes) targetNodes.concat(Array.from(nodes));
}
}
if (targetNodes && targetNodes.length > 0) {
btargetsFound = true;
//--- Found target node(s). Go through each and act if they are new.
for (var t = 0, tl = targetNodes.length; t < tl; t++) {
if (!targetNodes[t].getAttribute("wfke_found")) {
//--- Call the payload function.
var cancelFound = false;
try {
cancelFound = actionFunction (targetNodes[t]);
}
//--- Log errors to console rather than stopping altogether
catch (error) {
var name = actionFunction.name;
if (name)
name = 'in function "' + name + '":\n';
console.log ("waitForKeyElements: actionFunction error\n"
+ name + error);
}
if (cancelFound)
btargetsFound = false;
else
targetNodes[t].setAttribute("wfke_found", 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;
}
@z-aki
Copy link

z-aki commented Aug 27, 2025

thanks. But the script mentioned above doesn't work still, on the website linked above.

however this works https://z-aki.github.io/tampermonkey/2025/07/15/indian-bank-credit-card-expand-terms-and-conditions/

@adamhotep
Copy link
Author

@z-aki: that code uses @CoeJoder's waitForKeyElements() rather than this function. I'm glad you found something that works.

To others reading this, I highly suggest using nf.wait$() from my Nofus.js project. That function doesn't have special provisions for iframes because they haven't appeared necessary. Also notably, it utilizes a MutationObserver rather than a loop on a timer (as all waitForKeyElements() functions do). This means it runs every time the document changes rather than having to poll for changes periodically. This is both faster and more efficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment