How to wait until an element exists?

后端 未结 19 2077
广开言路
广开言路 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条回答
  •  萌比男神i
    2020-11-22 09:29

    Here's a function that acts as a thin wrapper around MutationObserver. The only requirement is that the browser support MutationObserver; there is no dependency on JQuery. Run the snippet below to see a working example.

    function waitForMutation(parentNode, isMatchFunc, handlerFunc, observeSubtree, disconnectAfterMatch) {
      var defaultIfUndefined = function(val, defaultVal) {
        return (typeof val === "undefined") ? defaultVal : val;
      };
    
      observeSubtree = defaultIfUndefined(observeSubtree, false);
      disconnectAfterMatch = defaultIfUndefined(disconnectAfterMatch, false);
    
      var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
          if (mutation.addedNodes) {
            for (var i = 0; i < mutation.addedNodes.length; i++) {
              var node = mutation.addedNodes[i];
              if (isMatchFunc(node)) {
                handlerFunc(node);
                if (disconnectAfterMatch) observer.disconnect();
              };
            }
          }
        });
      });
    
      observer.observe(parentNode, {
        childList: true,
        attributes: false,
        characterData: false,
        subtree: observeSubtree
      });
    }
    
    // Example
    waitForMutation(
      // parentNode: Root node to observe. If the mutation you're looking for
      // might not occur directly below parentNode, pass 'true' to the
      // observeSubtree parameter.
      document.getElementById("outerContent"),
      // isMatchFunc: Function to identify a match. If it returns true,
      // handlerFunc will run.
      // MutationObserver only fires once per mutation, not once for every node
      // inside the mutation. If the element we're looking for is a child of
      // the newly-added element, we need to use something like
      // node.querySelector() to find it.
      function(node) {
        return node.querySelector(".foo") !== null;
      },
      // handlerFunc: Handler.
      function(node) {
        var elem = document.createElement("div");
        elem.appendChild(document.createTextNode("Added node (" + node.innerText + ")"));
        document.getElementById("log").appendChild(elem);
      },
      // observeSubtree
      true,
      // disconnectAfterMatch: If this is true the hanlerFunc will only run on
      // the first time that isMatchFunc returns true. If it's false, the handler
      // will continue to fire on matches.
      false);
    
    // Set up UI. Using JQuery here for convenience.
    
    $outerContent = $("#outerContent");
    $innerContent = $("#innerContent");
    
    $("#addOuter").on("click", function() {
      var newNode = $("
    Outer
    "); $outerContent.append(newNode); }); $("#addInner").on("click", function() { var newNode = $("
    Inner
    "); $innerContent.append(newNode); });
    .content {
      padding: 1em;
      border: solid 1px black;
      overflow-y: auto;
    }
    #innerContent {
      height: 100px;
    }
    #outerContent {
      height: 200px;
    }
    #log {
      font-family: Courier;
      font-size: 10pt;
    }
    
    

    Create some mutations

    Log

提交回复
热议问题