您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Be smart!
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/454354/1123248/yssWaitForNode.js
// ==UserScript== // @name yssWaitForNode // @namespace https://ysslang.com/ // @version 1.2.1 // @description Be smart! // @author ysslang // @match *://*/* // @note https://greasyfork.org/scripts/454354 // @grant none // ==/UserScript== class WaitForNode { #currentURL; #observerList = []; #waitList = []; constructor() { this.#currentURL = window.location.href; } #checkIfUrlMatch(matcher) { var result = false; if (matcher === undefined || matcher === null) result = false; if (typeof matcher === "string") result = new RegExp(matcher.trim()).test(this.#currentURL); if (matcher instanceof RegExp) result = matcher.test(this.#currentURL); return result; } #determineParentElement(arg) { var result = document.body; if (typeof arg === "string" && document.querySelector(arg)) result = document.querySelector(arg); if (arg instanceof Element) result = arg; return result; } #mergeOptions(options) { options = options || {}; var result = { immediate: [options.immediate, options.imdt].find((e) => e) || true, recursive: [options.recursive, options.rcs].find((e) => e) || true, once: [options.once].find((e) => e) || false, subtree: [options.subtree, options.sbt].find((e) => e) || true, childList: [options.childList, options.cld].find((e) => e) || true, parentEl: this.#determineParentElement(options.parent), }; return result; } #extractMatchedElements(mutations, selector, recursive) { const matchedElements = []; for (const { addedNodes } of mutations) { for (const node of addedNodes) { if (!node.tagName) continue; else if (node.matches(selector)) matchedElements.push(node); else if (recursive && node.firstElementChild) matchedElements.push(...node.querySelectorAll(selector)); } } return matchedElements; } #on(selector, callback, options) { if (options.immediate) { [...options.parentEl.querySelectorAll(selector)].forEach(callback); } const observer = new MutationObserver((mutations) => { const elements = this.#extractMatchedElements(mutations, selector, options.recursive); elements.forEach(callback); if (elements && options.once) this.disconnect(); }); observer.observe(options.parentEl, { subtree: options.subtree, childList: options.childList, }); this.#observerList.push(observer); return observer; } #injectStyle(styleString) { const style = document.createElement('style'); style.textContent = styleString; return document.head.append(style); } add(name, url, selector, callback, options) { if(url === '') url = ['.*']; const urls = Array.isArray(url) ? url : [url]; if (!urls.some(this.#checkIfUrlMatch, this)) return; const opts = this.#mergeOptions(options); const observer = this.#on(selector, callback, opts); this.#waitList.push({'name': name, 'url': url, 'selector': selector, 'callback': callback, 'options': opts, 'observer': observer}); } addCss(name, url, cssString) { if(url === '') url = ['.*']; const urls = Array.isArray(url) ? url : [url]; if (!urls.some(this.#checkIfUrlMatch, this)) return; this.#injectStyle(cssString); } stopAll() { while (this.#observerList.length) this.#observerList.pop().disconnect(); } } const WFN = new WaitForNode();