我正在 Chrome 中开发一个扩展程序,我想知道:找出元素何时存在的最佳方法是什么?使用普通的 javascript,间隔检查直到元素存在,或者 jQuery 是否有一些简单的方法来做到这一点?
如何等到元素存在?
IT技术
javascript
jquery
google-chrome
google-chrome-extension
                    2021-01-27 00:45:07
                
                    
                
            
        6个回答
            DOMNodeInserted由于性能问题,与其他 DOM 突变事件一起被弃用 - 推荐的方法是使用MutationObserver来观察 DOM。不过,它仅在较新的浏览器中受支持,因此您应该DOMNodeInserted在MutationObserver不可用时返回。
let observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    if (!mutation.addedNodes) return
    for (let i = 0; i < mutation.addedNodes.length; i++) {
      // do things to your newly added nodes here
      let node = mutation.addedNodes[i]
    }
  })
})
observer.observe(document.body, {
    childList: true
  , subtree: true
  , attributes: false
  , characterData: false
})
// stop watching using:
observer.disconnect()
我遇到了同样的问题,所以我继续为它编写了一个插件。
$(selector).waitUntilExists(function);
代码:
;(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));
这是一个核心 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);
    }
  })();
}
此调用将查找id="div1"每1000毫秒一次的 HTML 标记。如果找到该元素,它将显示一条警报消息Hi。如果9000毫秒后未找到元素,则此函数将停止执行。
参数:
selector: String : 此函数查找元素 ${selector}。callback:Function : 这是一个在找到元素时将被调用的函数。checkFrequencyInMs: Number : 此函数每 ${checkFrequencyInMs} 毫秒检查此元素是否存在。timeoutInMs: 数字 : 可选。此函数在 ${timeoutInMs} 毫秒后停止查找元素。
注意:选择器在https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector 中有解释
这是一个使用MutationObserver api的简单解决方案。
- 不 
jQuery - 不 
Timer - 没有第三方库
 Promise基于并与async/await
我已经在几个项目中使用过它。
function waitForElm(selector) {
    return new Promise(resolve => {
        if (document.querySelector(selector)) {
            return resolve(document.querySelector(selector));
        }
        const observer = new MutationObserver(mutations => {
            if (document.querySelector(selector)) {
                resolve(document.querySelector(selector));
                observer.disconnect();
            }
        });
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    });
}
要使用它:
waitForElm('.some-class').then((elm) => {
    console.log('Element is ready');
    console.log(elm.textContent);
});
或者使用异步/等待:
const elm = await waitForElm('.some-class');
我使用这种方法来等待一个元素出现,以便在那之后执行其他函数。
假设doTheRestOfTheStuff(parameters)只有在带有 ID 的元素the_Element_ID出现或完成加载后才应调用函数,我们可以使用,
var existCondition = setInterval(function() {
 if ($('#the_Element_ID').length) {
    console.log("Exists!");
    clearInterval(existCondition);
    doTheRestOfTheStuff(parameters);
 }
}, 100); // check every 100ms