How can I determine if a dynamically-created DOM element has been added to the DOM?

后端 未结 11 904
滥情空心
滥情空心 2020-12-02 20:07

According to spec, only the BODY and FRAMESET elements provide an \"onload\" event to attach to, but I would like to know when a dynamically-create

相关标签:
11条回答
  • 2020-12-02 20:44

    In a perfect world you could hook the mutation events. I have doubts that they work reliably even on standards browsers. It sounds like you've already implemented a mutation event so you could possibly add this to use a native mutation event rather than timeout polling on browsers that support those.

    I've seen DOM-change implementations that monitor changes by comparing document.body.innerHTML to last saved .innerHTML, which isn't exactly elegant (but works). Since you're ultimately going to check if a specific node has been added yet, then you're better off just checking that each interrupt.

    Improvements I can think of are using .offsetParent rather than .parentNode as it will likely cut a few parents out of your loop (see comments). Or using compareDocumentIndex() on all but IE and testing .sourceIndex propery for IE (should be -1 if node isn't in the DOM).

    This might also help: X browser compareDocumentIndex implementaion by John Resig.

    0 讨论(0)
  • 2020-12-02 20:44

    You want the DOMNodeInserted event (or DOMNodeInsertedIntoDocument).

    Edit: It is entirely possible these events are not supported by IE, but I can't test that right now.

    0 讨论(0)
  • 2020-12-02 20:45

    Neither of DOMNodeInserted or DOMNodeInsertedIntoDocument events is supported in IE. Another missing from IE [only] feature of DOM is compareDocumentPosition function that is designed to do what its name suggests.

    As for the suggested solution, I think there is no better one (unless you do some dirty tricks like overwriting native DOM members implementations)

    Also, correcting the title of the question: dynamically created Element is part of the DOM from the moment it is created, it can be appended to a document fragment, or to another element, but it might not be appended to a document.

    I also think that the problem you described is not the problem that you have, this one looks to be rather one of the potential solutions to you problem. Can you probably explain in details the use case?

    0 讨论(0)
  • 2020-12-02 20:50

    The most straightforward answer is to make use of the Node.contains method, supported by Chrome, Firefox (Gecko), Internet Explorer, Opera, and Safari. Here is an example:

    var el = document.createElement("div");
    console.log(document.body.contains(el)); // false
    document.body.appendChild(el);
    console.log(document.body.contains(el)); // true
    document.body.removeChild(el);
    console.log(document.body.contains(el)); // false
    

    Ideally, we would use document.contains(el), but that doesn't work in IE, so we use document.body.contains(el).

    Unfortunately, you still have to poll, but checking whether an element is in the document yet is very simple:

    setTimeout(function test() {
      if (document.body.contains(node)) {
        func();
      } else {
        setTimeout(test, 50);
      }
    }, 50);
    

    If you're okay with adding some CSS to your page, here's another clever technique that uses animations to detect node insertions: http://www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/

    0 讨论(0)
  • 2020-12-02 20:57

    A MutationObserver is what you should use to detect when an element has been added to the DOM. MutationObservers are now widely supported across all modern browsers (Chrome 26+, Firefox 14+, IE11, Edge, Opera 15+, etc).

    Here's a simple example of how you can use a MutationObserver to listen for when an element is added to the DOM.

    For brevity, I'm using jQuery syntax to build the node and insert it into the DOM.

    var myElement = $("<div>hello world</div>")[0];
    
    var observer = new MutationObserver(function(mutations) {
       if (document.contains(myElement)) {
            console.log("It's in the DOM!");
            observer.disconnect();
        }
    });
    
    observer.observe(document, {attributes: false, childList: true, characterData: false, subtree:true});
    
    $("body").append(myElement); // console.log: It's in the DOM!
    

    The observer event handler will trigger whenever any node is added or removed from the document. Inside the handler, we then perform a contains check to determine if myElement is now in the document.

    You don't need to iterate over each MutationRecord stored in mutations because you can perform the document.contains check directly upon myElement.

    To improve performance, replace document with the specific element that will contain myElement in the DOM.

    0 讨论(0)
提交回复
热议问题