519 Stimmen

Wie kann man warten, bis ein Element vorhanden ist?

Ich arbeite an einer Erweiterung in Chrome, und ich frage mich: Was ist der beste Weg, um herauszufinden, wann ein Element in Existenz kommt? Mit einfachen Javascript, mit einem Intervall, das überprüft, bis ein Element vorhanden ist, oder hat jQuery eine einfache Möglichkeit, dies zu tun?

659voto

Yong Wang Punkte 2952

Hier ist eine einfache Lösung unter Verwendung der MutationObserver api.

  1. Nein jQuery
  2. Nein Timer
  3. Keine Bibliotheken von Drittanbietern
  4. Promise basiert und funktioniert gut mit async/await

Ich habe es in mehreren Projekten verwendet.

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

Zur Verwendung:

waitForElm('.some-class').then((elm) => {
    console.log('Element is ready');
    console.log(elm.textContent);
});

Oder mit async/await:

const elm = await waitForElm('.some-class');

235voto

hughsk Punkte 3507

DOMNodeInserted wird zusammen mit den anderen DOM-Mutationsereignissen aufgrund von Leistungsproblemen veraltet sein - der empfohlene Ansatz ist die Verwendung einer MutationObserver um das DOM zu beobachten. Es wird allerdings nur in neueren Browsern unterstützt, daher sollten Sie auf DOMNodeInserted wenn MutationObserver ist nicht verfügbar.

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()

135voto

Etienne Tonnelier Punkte 1879

Hier ist eine zentrale JavaScript-Funktion, die auf die Anzeige eines Elements wartet (genauer gesagt, auf seine Einfügung in das 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);
    }
  })();
}

Dieser Aufruf sucht nach dem HTML-Tag, dessen id="div1" jede 1000 Millisekunden. Wenn das Element gefunden wird, wird eine Warnmeldung angezeigt Hallo . Wenn kein Element gefunden wird, nachdem 9000 Millisekunden, stoppt diese Funktion ihre Ausführung.

Parameter:

  1. selector : String : Diese Funktion sucht nach dem Element ${selector}.
  2. callback : Funktion : Dies ist eine Funktion, die aufgerufen wird, wenn das Element gefunden wird.
  3. checkFrequencyInMs : Number : Diese Funktion prüft alle ${checkFrequencyInMs} Millisekunden, ob dieses Element existiert.
  4. timeoutInMs : Nummer : Optional. Diese Funktion beendet die Suche nach dem Element nach ${timeoutInMs} Millisekunden.

NB : Selektoren werden erklärt unter https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

121voto

Ryan Lester Punkte 2343

Ich hatte das gleiche Problem, also habe ich eine Plugin für sie.

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

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

54voto

prime Punkte 12730

Ich habe diesen Ansatz verwendet, um zu warten, bis ein Element erscheint, damit ich die anderen Funktionen danach ausführen kann.

Sagen wir doTheRestOfTheStuff(parameters) Funktion sollte erst nach dem Element mit der ID aufgerufen werden the_Element_ID erscheint oder das Laden beendet ist, können wir verwenden,

var existCondition = setInterval(function() {
 if ($('#the_Element_ID').length) {
    console.log("Exists!");
    clearInterval(existCondition);
    doTheRestOfTheStuff(parameters);
 }
}, 100); // check every 100ms

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X