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?
Antworten
Zu viele Anzeigen?Hier ist eine einfache Lösung unter Verwendung der MutationObserver api.
- Nein
jQuery
- Nein
Timer
- Keine Bibliotheken von Drittanbietern
Promise
basiert und funktioniert gut mitasync/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');
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()
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:
selector
: String : Diese Funktion sucht nach dem Element ${selector}.callback
: Funktion : Dies ist eine Funktion, die aufgerufen wird, wenn das Element gefunden wird.checkFrequencyInMs
: Number : Diese Funktion prüft alle ${checkFrequencyInMs} Millisekunden, ob dieses Element existiert.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
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));
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
- See previous answers
- Weitere Antworten anzeigen