-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*--- 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; | |
| } |
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
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/