How to wait until an element exists?

后端 未结 19 2141
广开言路
广开言路 2020-11-22 09:14

I\'m working on an Extension in Chrome, and I\'m wondering: what\'s the best way to find out when an element comes into existence? Using plain javascript, with an interval t

19条回答
  •  庸人自扰
    2020-11-22 09:50

    A solution returning a Promise and allowing to use a timeout (compatible IE 11+).

    For a single element (type Element):

    "use strict";
    
    function waitUntilElementLoaded(selector) {
        var timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    
        var start = performance.now();
        var now = 0;
    
        return new Promise(function (resolve, reject) {
            var interval = setInterval(function () {
                var element = document.querySelector(selector);
    
                if (element instanceof Element) {
                    clearInterval(interval);
    
                    resolve();
                }
    
                now = performance.now();
    
                if (now - start >= timeout) {
                    reject("Could not find the element " + selector + " within " + timeout + " ms");
                }
            }, 100);
        });
    }
    

    For multiple elements (type NodeList):

    "use strict";
    
    function waitUntilElementsLoaded(selector) {
        var timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    
        var start = performance.now();
        var now = 0;
    
        return new Promise(function (resolve, reject) {
            var interval = setInterval(function () {
                var elements = document.querySelectorAll(selector);
    
                if (elements instanceof NodeList) {
                    clearInterval(interval);
    
                    resolve(elements);
                }
    
                now = performance.now();
    
                if (now - start >= timeout) {
                    reject("Could not find elements " + selector + " within " + timeout + " ms");
                }
            }, 100);
        });
    }
    

    Examples:

    waitUntilElementLoaded('#message', 800).then(function(element) {
        // element found and available
    
        element.innerHTML = '...';
    }).catch(function() {
        // element not found within 800 milliseconds
    });
    
    waitUntilElementsLoaded('.message', 10000).then(function(elements) {
        for(const element of elements) {
            // ....
        }
    }).catch(function(error) {
        // elements not found withing 10 seconds
    });
    

    Works for both a list of elements and a single element.

提交回复
热议问题