我正在Chrome中开发一个扩展,我想知道:当一个元素出现时,最好的方法是什么?使用纯javascript,间隔检查,直到一个元素存在,或jQuery有一些简单的方法来做到这一点?


当前回答

简单的Javascript。

cont elementExist = setInterval(() => {
    var elm = document.getElementById("elementId")
    if (elm!=null)
         // call your function here to do something
        clearInterval(elementExist);
    }
}, 100);

注意:这将阻塞其他执行

其他回答

这里有一个核心JavaScript函数,用于等待元素的显示(好吧,将其插入到DOM中更准确)。

// Call the below function
waitForElementToDisplay("#div1",function(){alert("Hi");},1000,9000);

function waitForElementToDisplay(selector, callback, checkFrequencyInMs, timeoutInMs) {
  var startTimeInMs = Date.now();
  (function loopSearch() {
    if (document.querySelector(selector) != null) {
      callback();
      return;
    }
    else {
      setTimeout(function () {
        if (timeoutInMs && Date.now() - startTimeInMs > timeoutInMs)
          return;
        loopSearch();
      }, checkFrequencyInMs);
    }
  })();
}

这个调用将每1000毫秒查找id="div1"的HTML标记。如果找到元素,它将显示一条警报消息Hi。如果在9000毫秒后没有找到任何元素,该函数将停止执行。

参数:

String:该函数查找元素${selector}。 callback: Function:这是一个函数,如果找到元素将被调用。 checkFrequencyInMs: Number:该函数每${checkFrequencyInMs}毫秒检查该元素是否存在。 timeoutInMs: Number:可选。该函数在${timeoutInMs}毫秒后停止查找元素。

注意:选择器的解释在https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

我通常使用标签管理器的这个片段:

<script>
(function exists() {
  if (!document.querySelector('<selector>')) {
    return setTimeout(exists);
  }
  // code when element exists
})();  
</script>

我也有同样的问题,所以我继续写了一个插件。

$(选择).waitUntilExists(函数);

代码:

;(function ($, window) {

var intervals = {};
var removeListener = function(selector) {

    if (intervals[selector]) {

        window.clearInterval(intervals[selector]);
        intervals[selector] = null;
    }
};
var found = 'waitUntilExists.found';

/**
 * @function
 * @property {object} jQuery plugin which runs handler function once specified
 *           element is inserted into the DOM
 * @param {function|string} handler 
 *            A function to execute at the time when the element is inserted or 
 *            string "remove" to remove the listener from the given selector
 * @param {bool} shouldRunHandlerOnce 
 *            Optional: if true, handler is unbound after its first invocation
 * @example jQuery(selector).waitUntilExists(function);
 */

$.fn.waitUntilExists = function(handler, shouldRunHandlerOnce, isChild) {

    var selector = this.selector;
    var $this = $(selector);
    var $elements = $this.not(function() { return $(this).data(found); });

    if (handler === 'remove') {

        // Hijack and remove interval immediately if the code requests
        removeListener(selector);
    }
    else {

        // Run the handler on all found elements and mark as found
        $elements.each(handler).data(found, true);

        if (shouldRunHandlerOnce && $this.length) {

            // Element was found, implying the handler already ran for all 
            // matched elements
            removeListener(selector);
        }
        else if (!isChild) {

            // If this is a recurring search or if the target has not yet been 
            // found, create an interval to continue searching for the target
            intervals[selector] = window.setInterval(function () {

                $this.waitUntilExists(handler, shouldRunHandlerOnce, true);
            }, 500);
        }
    }

    return $this;
};

}(jQuery, window));

一个返回承诺的解决方案,并允许使用超时(兼容IE 11+)。

对于单个元素(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);
    });
}

对于多个元素(类型为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);
    });
}

例子:

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
});

既适用于元素列表,也适用于单个元素。

我认为仍然没有任何答案在这里与简单易读的工作实例。使用MutationObserver接口来检测DOM的变化,如下所示:

var observer = new MutationObserver(function(mutations) { if ($("p").length) { console.log("Exist, lets do something"); observer.disconnect(); //We can disconnect observer once the element exist if we dont want observe more changes in the DOM } }); // Start observing observer.observe(document.body, { //document.body is node target to observe childList: true, //This is a must have for the observer with subtree subtree: true //Set to true if changes must also be observed in descendants. }); $(document).ready(function() { $("button").on("click", function() { $("p").remove(); setTimeout(function() { $("#newContent").append("<p>New element</p>"); }, 2000); }); }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button>New content</button> <div id="newContent"></div>

注意:关于MutationObserver的西班牙语Mozilla文档更多 详情,如果你想了解更多信息。