Javascript 如何等到元素存在?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5525071/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:38:21  来源:igfitidea点击:

How to wait until an element exists?

javascriptjquerygoogle-chromegoogle-chrome-extension

提问by mattsven

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 that checks until an element exists, or does jQuery have some easy way to do this?

我正在 Chrome 中开发一个扩展程序,我想知道:找出元素何时存在的最佳方法是什么?使用普通的 javascript,间隔检查直到元素存在,或者 jQuery 是否有一些简单的方法来做到这一点?

采纳答案by hughsk

DOMNodeInsertedis being deprecated, along with the other DOM mutation events, because of performance issues - the recommended approach is to use a MutationObserverto watch the DOM. It's only supported in newer browsers though, so you should fall back onto DOMNodeInsertedwhen MutationObserverisn't available.

DOMNodeInserted由于性能问题,与其他 DOM 突变事件一起被弃用 - 推荐的方法是使用MutationObserver来观察 DOM。不过,它仅在较新的浏览器中受支持,因此您应该DOMNodeInsertedMutationObserver不可用时退回。

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if (!mutation.addedNodes) return

    for (var i = 0; i < mutation.addedNodes.length; i++) {
      // do things to your newly added nodes here
      var node = mutation.addedNodes[i]
    }
  })
})

observer.observe(document.body, {
    childList: true
  , subtree: true
  , attributes: false
  , characterData: false
})

// stop watching using:
observer.disconnect()

回答by Ryan Lester

I was having this same problem, so I went ahead and wrote a pluginfor it.

我遇到了同样的问题,所以我继续为它编写了一个插件

$(selector).waitUntilExists(function);

$(selector).waitUntilExists(function);

Code:

代码:

;(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') {

        // HiHyman 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));

回答by Etienne Tonnelier

Here is a core JavaScript function to wait for the display of an element.

这是一个等待元素显示的核心 JavaScript 函数。

Parameters:

参数:

  1. selector: This function looks for the element ${selector}
  2. time: This function checks whether this element exists every ${time} milliseconds.

    function waitForElementToDisplay(selector, time) {
            if(document.querySelector(selector)!=null) {
                alert("The element is displayed, you can put your code instead of this alert.")
                return;
            }
            else {
                setTimeout(function() {
                    waitForElementToDisplay(selector, time);
                }, time);
            }
        }
    
  1. selector: 这个函数寻找元素 ${selector}
  2. time:此函数每 ${time} 毫秒检查此元素是否存在。

    function waitForElementToDisplay(selector, time) {
            if(document.querySelector(selector)!=null) {
                alert("The element is displayed, you can put your code instead of this alert.")
                return;
            }
            else {
                setTimeout(function() {
                    waitForElementToDisplay(selector, time);
                }, time);
            }
        }
    

As an example, setting selector="#div1"and time=5000will look for the HTML tag whose id="div1"every 5000 milliseconds.

例如,设置selector="#div1"time=5000将查找id="div1"每 5000 毫秒一次的 HTML 标记。

回答by serg

You can listen to DOMNodeInsertedor DOMSubtreeModifiedevents which fire whenever a new element is added to the DOM.

您可以监听DOMNodeInsertedDOMSubtreeModified每当向 DOM 添加新元素时触发的事件。

There is also LiveQueryjQuery plugin which would detect when a new element is created:

还有一个LiveQueryjQuery 插件可以检测新元素的创建时间:

$("#future_element").livequery(function(){
    //element created
});

回答by prime

I used this approach to wait for an element to appear so I can execute the other functions after that.

我使用这种方法来等待一个元素出现,这样我就可以在那之后执行其他函数。

Let's say doTheRestOfTheStuff(parameters)function should only be called after the element with ID the_Element_IDappears or finished loading, we can use,

假设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

回答by Splynx

You can do

你可以做

$('#yourelement').ready(function() {

});

Please note that this will only work if the element is present in the DOM when being requested from the server. If the element is being dynamically added via JavaScript, it will not work and you may need to look at the other answers.

请注意,这仅当从服务器请求时元素存在于 DOM 中时才有效。如果元素是通过 JavaScript 动态添加的,它将不起作用,您可能需要查看其他答案。

回答by SilverSurfer

I think that still there isnt any answer here with easy and readable working example. Use MutationObserverinterfaceto detect DOM changes, like this:

我认为这里仍然没有任何简单易读的工作示例的答案。使用MutationObserverinterface检测 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>

Note:Spanish Mozilladocs about MutationObserverare more detailed if you want more information.

注意:如果您想了解更多信息,西班牙语 Mozilla文档MutationObserver会更详细。

回答by Diego Fortes

Simply add the selector you want. Once the element is found you can have access to in the callback function.

只需添加您想要的选择器。找到元素后,您可以访问回调函数。

const waitUntilElementExists = (selector, callback) => {
const el = document.querySelector(selector);

if (el){
    return callback(el);
}

setTimeout(() => waitUntilElementExists(selector, callback), 500);
}

waitUntilElementExists('.wait-for-me', (el) => console.log(el));

回答by Hedley Smith

For a simple approach using jQuery I've found this to work well:

对于使用 jQuery 的简单方法,我发现它运行良好:

  // Wait for element to exist.
  function elementLoaded(el, cb) {
    if ($(el).length) {
      // Element is now loaded.
      cb($(el));
    } else {
      // Repeat every 500ms.
      setTimeout(function() {
        elementLoaded(el, cb)
      }, 500);
    }
  };

  elementLoaded('.element-selector', function(el) {
    // Element is ready to use.
    el.click(function() {
      alert("You just clicked a dynamically inserted element");
    });
  });

Here we simply check every 500ms to see whether the element is loaded, when it is, we can use it.

这里我们简单地每 500 毫秒检查一次元素是否被加载,当它加载时,我们就可以使用它。

This is especially useful for adding click handlers to elements which have been dynamically added to the document.

这对于向已动态添加到文档的元素添加点击处理程序特别有用。

回答by b3wii

How about the insertionQuerylibrary?

怎么样insertionQuery库?

insertionQuery uses CSS Animation callbacks attached to the selector(s) specified to run a callback when an element is created. This method allows callbacks to be run whenever an element is created, not just the first time.

insertQuery 使用附加到指定的选择器的 CSS 动画回调,以在创建元素时运行回调。此方法允许在创建元素时运行回调,而不仅仅是第一次。

From github:

来自 github:

Non-dom-event way to catch nodes showing up. And it uses selectors.

It's not just for wider browser support, It can be better than DOMMutationObserver for certain things.

Why?

  • Because DOM Events slow down the browser and insertionQuery doesn't
  • Because DOM Mutation Observer has less browser support than insertionQuery
  • Because with insertionQuery you can filter DOM changes using selectors without performance overhead!

Widespread support!

IE10+ and mostly anything else (including mobile)

捕捉节点出现的非 dom 事件方式。它使用选择器。

它不仅仅是为了更广泛的浏览器支持,它在某些方面可能比 DOMMutationObserver 更好。

为什么?

  • 因为 DOM 事件会减慢浏览器的速度,而插入查询不会
  • 因为 DOM Mutation Observer 的浏览器支持比 insertQuery 少
  • 因为通过插入查询,您可以使用选择器过滤 DOM 更改而不会产生性能开销!

广泛支持!

IE10+ 和大多数其他东西(包括移动设备)