observe

observe and wait for elements

当前为 2025-10-11 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/552301/1675865/observe.js

// ==UserScript==
// @name         observe
// @license      MIT
// @version      1.0
// @description  observe and wait for elements
// @author       tukars
// @match        *://*/*
// ==/UserScript==

const Observe = (function() {
    const timeStamp = function() {
        const now = new Date();
        const pad = (num, size) => String(num).padStart(size, "0");
        
        const hours = pad(now.getHours(), 2);
        const minutes = pad(now.getMinutes(), 2);
        const seconds = pad(now.getSeconds(), 2);
        const milliseconds = pad(now.getMilliseconds(), 3);
        
        return `${hours}:${minutes}:${seconds}.${milliseconds}`;
    }
    
    const contextPrint = function(message, ENABLE_DEBUG_LOGGING) {
        const messageTime = () => `[${message}] ${timeStamp()} -`;
        
        const log = function (...args) {console.log(messageTime(), ...args);};
        const warn = function (...args) {console.warn(messageTime(), ...args);};
        const error = function (...args) {console.error(messageTime(), ...args);};
        const info = function (...args) {console.info(messageTime(), ...args);};
        var debug = function (...args) {console.debug(messageTime(), ...args);};
        if (!ENABLE_DEBUG_LOGGING) {debug = function () {};}
        
        return { log, warn, error, info, debug };
    }
    
    const observeChildren = function(element, config, callback) {
        const observer = new MutationObserver((mutationsList) => {
            for (const mutation of mutationsList) {
                if (mutation.type === "childList") {
                    callback(Array.from(mutation.addedNodes));
                }
            }
        });
        var use_config;
        if (!config) {use_config = {childList: true, subtree: false };} 
        else {use_config = config;}
        observer.observe(element, use_config);
        return observer;
    }
    
    const observeChildrenWithFilter = function(element, config, filter, callback) {
        return observeChildren(element, config, (addedNodes) =>
            callback(addedNodes.filter(filter))
        );
    }
    
    const observeChildrenWithTags = function(element, config, filterTags, callback) {
        return observeChildrenWithFilter(
            element,
            config,
            (node) =>
                node.nodeType === Node.ELEMENT_NODE &&
                filterTags.includes(node.tagName.toLowerCase()),
            callback
        );
    }
    
    const observeAndHandle = function(element, tags, fun, config) {
        var use_config;
        if (!config) {use_config = {childList: true, subtree: true };} 
        else {use_config = config;}
        observeChildrenWithTags(element, use_config, tags, (nodes) =>
            nodes.forEach((node) => fun(node))
        );
    }
    
    function waitForElement(selector, callback) {
        const element = document.querySelector(selector);
        if (element) {
            callback(element);
        } else {
            const observer = new MutationObserver((_, obs) => {
                const el = document.querySelector(selector);
                if (el) {
                    obs.disconnect();
                    callback(el);
                }
            });
            observer.observe(document.body, {childList: true, subtree: true,});
        }
    }
    
    return {
        timeStamp,
        contextPrint,
        observeChildren,
        observeChildrenWithFilter,
        observeChildrenWithTags,
        observeAndHandle,
        waitForElement
    }
})();