detect when an element is ready
Dieses Skript sollte nicht direkt installiert werden. Es handelt sich hier um eine Bibliothek für andere Skripte, welche über folgenden Befehl in den Metadaten eines Skriptes eingebunden wird // @require https://update.greasyfork.org/scripts/419640/1776135/onElementReady.js
// ==UserScript== // @name onElementReady // @namespace https://zachhardesty.com // @exclude * // @homepage https://github.com/zachhardesty7/tamper-monkey-scripts-collection/raw/master/utils/onElementReady.js // @homepageURL https://github.com/zachhardesty7/tamper-monkey-scripts-collection/raw/master/utils/onElementReady.js // @license GPL-3.0-only; http://www.gnu.org/licenses/gpl-3.0.txt // @copyright 2026, Zach Hardesty (https://zachhardesty.com/) // @version 0.10.2 // @description Detect any new DOM Element by its CSS Selector, then trigger a function. Includes Promise & Callback interface. Based on ES6 MutationObserver. Ships legacy waitForKeyElements interface, too. // @author Zach Hardesty <[email protected]> (https://github.com/zachhardesty7) // ==/UserScript== // ORIGINAL CODE BY sidneys: https://gist.github.com/sidneys/ee7a6b80315148ad1fb6847e72a22313 // Remember already found elements via this attribute const QUERIED_ATTRIBUTE_NAME = "was-queried" const DEFAULT_OPTIONS = /** @type {const} @satisfies {OnElementReadyOptions} */ ({ findFirst: false, findOnce: true, root: document, }) /** * Internal function used by {@link onElementReady} to query for new DOM nodes matching a * specified selector. * * @private * @param {string} selector * @param {OnElementReadyOptions} options * @param {OnElementReadyCallback} callback */ // eslint-disable-next-line prefer-const let queryForElements = (selector, options, callback) => { const finalOptions = { ...DEFAULT_OPTIONS, ...options } // Search for elements by selector const elementList = finalOptions.root?.querySelectorAll(selector) || [] for (const element of elementList) { if (element.hasAttribute(QUERIED_ATTRIBUTE_NAME)) { continue } element.setAttribute(QUERIED_ATTRIBUTE_NAME, "true") callback(element) // run reset after 2 seconds if (!finalOptions.findOnce) { setTimeout(() => { element.removeAttribute(QUERIED_ATTRIBUTE_NAME) }, 2000) } } } /** * Wait for elements with a given CSS selector to enter the DOM. Returns a `Promise` * resolving with found/changed element and triggers a callback for every found/changed * element. * * @param {string} selector * @param {OnElementReadyOptions} [options] * @param {OnElementReadyCallback} [callback] * @returns {OnElementReadyReturn} * @public */ // eslint-disable-next-line prefer-const let onElementReady = (selector, options = DEFAULT_OPTIONS, callback = () => {}) => { const finalOptions = { ...DEFAULT_OPTIONS, ...options } return new Promise((resolve) => { // Initial Query queryForElements(selector, finalOptions, (element) => { resolve(element) callback(element) }) // Continuous Query const observer = new MutationObserver(() => { // DOM Changes detected queryForElements(selector, finalOptions, (element) => { resolve(element) callback(element) // stop querying after first successful pass and remove mutation observer, // calling multiple times (when mutliple matching elements) seems to work fine if (finalOptions.findFirst) { observer.disconnect() } }) }) // Observe DOM Changes observer.observe(document.documentElement, { attributes: false, childList: true, subtree: true, }) }) } /** * @deprecated * @param {string} selector * @param {OnElementReadyCallback} [callback] * @param {OnElementReadyOptions} [options] * @returns {OnElementReadyReturn} * @public */ // eslint-disable-next-line no-unused-vars, prefer-const let waitForKeyElements = (selector, callback, options) => onElementReady(selector, options, callback)