Created
January 13, 2023 10:32
-
-
Save kols/5cb2d0b834dc2f4f6d854786f0ba8a90 to your computer and use it in GitHub Desktop.
waitForKeyElements.js
This file contains 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
/** | |
* A utility function for userscripts that detects and handles AJAXed content. | |
* | |
* @example | |
* waitForKeyElements("div.comments", (element) => { | |
* element.innerHTML = "This text inserted by waitForKeyElements()."; | |
* }); | |
* | |
* waitForKeyElements(() => { | |
* const iframe = document.querySelector('iframe'); | |
* if (iframe) { | |
* const iframeDoc = iframe.contentDocument || iframe.contentWindow.document; | |
* return iframeDoc.querySelectorAll("div.comments"); | |
* } | |
* return null; | |
* }, callbackFunc); | |
* | |
* @param {(string|function)} selectorOrFunction - The selector string or function. | |
* @param {function} callback - The callback function; takes a single DOM element as parameter. | |
* If returns true, element will be processed again on subsequent iterations. | |
* @param {boolean} [waitOnce=true] - Whether to stop after the first elements are found. | |
* @param {number} [interval=300] - The time (ms) to wait between iterations. | |
* @param {number} [maxIntervals=-1] - The max number of intervals to run (negative number for unlimited). | |
*/ | |
function waitForKeyElements(selectorOrFunction, callback, waitOnce, interval, maxIntervals) { | |
if (typeof waitOnce === "undefined") { | |
waitOnce = true; | |
} | |
if (typeof interval === "undefined") { | |
interval = 300; | |
} | |
if (typeof maxIntervals === "undefined") { | |
maxIntervals = -1; | |
} | |
var targetNodes = (typeof selectorOrFunction === "function") | |
? selectorOrFunction() | |
: document.querySelectorAll(selectorOrFunction); | |
var targetsFound = targetNodes && targetNodes.length > 0; | |
if (targetsFound) { | |
targetNodes.forEach(function(targetNode) { | |
var attrAlreadyFound = "data-userscript-alreadyFound"; | |
var alreadyFound = targetNode.getAttribute(attrAlreadyFound) || false; | |
if (!alreadyFound) { | |
var cancelFound = callback(targetNode); | |
if (cancelFound) { | |
targetsFound = false; | |
} | |
else { | |
targetNode.setAttribute(attrAlreadyFound, true); | |
} | |
} | |
}); | |
} | |
if (maxIntervals !== 0 && !(targetsFound && waitOnce)) { | |
maxIntervals -= 1; | |
setTimeout(function() { | |
waitForKeyElements(selectorOrFunction, callback, waitOnce, interval, maxIntervals); | |
}, interval); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment