Wait For Selector

Waits for selectors to match newly added nodes

2021/09/14のページです。最新版はこちら

このスクリプトは単体で利用できません。右のようなメタデータを含むスクリプトから、ライブラリとして読み込まれます: // @require https://update.greatest.deepsurf.us/scripts/432418/970669/Wait%20For%20Selector.js

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Wait For Selector
// @version      0.1.0
// @description  Waits for selectors to match newly added nodes
// @author       Kumirei
// @include      *community.wanikani.com*
// @grant        none
// ==/UserScript==

(function($) {
    // Create new observer on body to monitor all DOM changes
    let observer = new MutationObserver(mutationHandler)
    observer.observe(document.getElementsByTagName('body')[0], {childList: true, subtree: true})

    // Interface for interacting with the library
    let interface = {
        version: GM_info.script.version,
        observer: observer,
        wait: waitForSelector,
        unwait: unwaitID,
        waits: {},
        waitsByID: {},
        nextID: 0
    }

    // Start
    installInterface()

    // Creates a new entry to search for whenever a new element is added to the DOM
    function waitForSelector(preSelector, selector, callback) {
        if (selector.match(`${preSelector}$`) === null) throw ('preSelector must match the end of the selector')
        if (!interface.waits[selector]) interface.waits[selector] = {}
        interface.waits[selector][interface.nextID] = callback
        interface.waits[selector].pre = preSelector
        interface.waitsByID[interface.nextID] = selector
        return interface.nextID++
    }

    // Deletes a previously registered selector
    function unwaitID(ID) {
        delete interface.waits[interface.waitsByID[ID]][ID]
    }

    // Makes sure that the public interface is the newest version and the same as the local one
    function installInterface() {
        let wfs = window.wkfe
        if (!wfs) window.wfs = interface
        else if (wfs.version < interface.version) {
            wfs.version = interface.version
            wfs.observer.disconnect()
            wfs.observer = interface.observer
            wfs.wait = interface.wait
            wfs.unwait = interface.unwait
        }
        interface = wfs || interface
    }

    // Searches the added nodes and matches them with the provided selectors. Calls the callback for every match.
    function mutationHandler(mutations) {
        for (let mutation of mutations) {
            let added = mutation.addedNodes
            for (let node of added) {
                if (node.nodeType === 1) {
                    let sibling = node.previousElementSibling
                    let target = sibling ? sibling : node.parentElement
                    for (let selector in interface.waits) {
                        let query = (sibling?'+ ':'> ')+interface.waits[selector].pre
                        $(target).find(query).each((i, e)=>{
                            $(selector).each((I, E)=>{
                                if (e.isSameNode(E)) {
                                    for (let callback of Object.values(interface.waits[selector])) {
                                        if (typeof callback === "function") callback(E)
                                    }
                                }
                            })
                        })
                    }
                }
            }
        }
    }
})(window.jQuery);