Wie kann überprüft werden, ob ein Element auf einer Seite geladen wurde, bevor ein Skript ausgeführt wird?
Lesezeit: 7 Minuten
Benutzer2052567
Also erstelle ich meine Seite in meiner Unternehmensvorlage, die uns nur den Zugriff auf den Hauptteil der Seite ermöglicht. Wir haben keinen Zugriff auf das Head-Tag und im unteren Teil der Seite sind Skripts geladen, auf die wir keinen Zugriff haben. Eines dieser Skripte lädt dynamisch ein Element auf die Seite. Ich muss ein anderes Skript für dieses Element ausführen, aber da das Element erst auf der Seite geladen wird, nachdem mein Skript bereits ausgeführt wurde, kann ich nicht auf dieses Element zugreifen. Gibt es eine Möglichkeit, zu überprüfen, ob dieses Element bereits auf der Seite geladen wurde, bevor ich mein Skript ausführe?
Lassen Sie mich wissen, wenn ich es besser erklären muss.
<head>Don't have access</head>
<body>
<!--Needs to manipulate the element created by the companyScript.js-->
<script src="https://stackoverflow.com/questions/34863788/myScript.js"></script>
<!--Script that runs after mine, which I don't have access too-->
<script src="companyScript.js">
/*Dynamically adds <div class="element"></div> to page*/
</script>
</body>
Schreiben Sie ein Skript, um Ihr Skript am Ende der Seite anzuhängen, damit es danach geladen wird
– Johnny 5
18. Januar 2016 um 20:49 Uhr
If ( $('.element').length )
– adeneo
18. Januar 2016 um 20:53 Uhr
Verwenden Sie den Code, der das Element hinzufügt, um Ihren Code auszuführen, der sich auf dieses Element auswirken würde. Benötigen Sie ein besseres Verständnis des Problems, um qualitativ hochwertigere Antworten zu erhalten und weniger zu raten
– charlietfl
18. Januar 2016 um 20:56 Uhr
@ johnny5, das sich nicht damit befasst, ob ein dynamisch hinzugefügtes Element vorhanden ist oder nicht
– charlietfl
18. Januar 2016 um 21:00 Uhr
I habe einmal mit einem Bär gekämpft.
Version 2022, mit MutationObserver
Den 2020-Code umgeschrieben, um a zu verwenden MutationObserver statt Umfragen.
/**
* Wait for an element before resolving a promise
* @param {String} querySelector - Selector of element to wait for
* @param {Integer} timeout - Milliseconds to wait before timing out, or 0 for no timeout
*/
function waitForElement(querySelector, timeout){
return new Promise((resolve, reject)=>{
var timer = false;
if(document.querySelectorAll(querySelector).length) return resolve();
const observer = new MutationObserver(()=>{
if(document.querySelectorAll(querySelector).length){
observer.disconnect();
if(timer !== false) clearTimeout(timer);
return resolve();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
if(timeout) timer = setTimeout(()=>{
observer.disconnect();
reject();
}, timeout);
});
}
waitForElement("#idOfElementToWaitFor", 3000).then(function(){
alert("element is loaded.. do stuff");
}).catch(()=>{
alert("element did not load in 3 seconds");
});
Version 2020, mit Versprechungen
Dieser Code fragt das DOM 10x/Sekunde ab und löst ein Promise auf, wenn es vor dem optionalen Timeout gefunden wird.
/**
* Wait for an element before resolving a promise
* @param {String} querySelector - Selector of element to wait for
* @param {Integer} timeout - Milliseconds to wait before timing out, or 0 for no timeout
*/
function waitForElement(querySelector, timeout=0){
const startTime = new Date().getTime();
return new Promise((resolve, reject)=>{
const timer = setInterval(()=>{
const now = new Date().getTime();
if(document.querySelector(querySelector)){
clearInterval(timer);
resolve();
}else if(timeout && now - startTime >= timeout){
clearInterval(timer);
reject();
}
}, 100);
});
}
waitForElement("#idOfElementToWaitFor", 3000).then(function(){
alert("element is loaded.. do stuff");
}).catch(()=>{
alert("element did not load in 3 seconds");
});
Ursprüngliche Antwort
function waitForElement(id, callback){
var poops = setInterval(function(){
if(document.getElementById(id)){
clearInterval(poops);
callback();
}
}, 100);
}
waitForElement("idOfElementToWaitFor", function(){
alert("element is loaded.. do stuff");
});
Genial! 😉 SO einfach… und doch effektiv! Der einzige Code, der effektiv auf Angular funktioniert, ist der Aufruf der Funktion on ngAfterViewInit() und das ist es! Vielen Dank!
– Pedro Ferreira
29. Oktober 2019 um 21:49 Uhr
Ich mochte Ihren 2020-Code, könnten Sie bitte die if-Anweisungen in der Funktion waitForElement erläutern?
– Mathew
23. August 2020 um 12:42 Uhr
Das ist ein sehr guter Code, der etwas erklärt werden muss, aber was dieser Code tut, ist zu erkennen, ob das Element geladen ist, und dann Dinge zu tun, was dieser Code nicht tut, ist, Dinge zu tun, WÄHREND das Element geladen wird
– Mathew
23. August 2020 um 12:44 Uhr
@Mathew – Das machen Versprechen, sie lassen dich Dinge tun, während du auf etwas anderes wartest. Das if -Anweisung prüft nur, ob das Element bereits existiert.
– I habe einmal mit einem Bär gekämpft.
24. August 2020 um 14:41 Uhr
@I habe einmal mit einem Bär gekämpft. Ich versuche zu deaktivieren observer.disconnect() in MutationObserver, um es immer am Laufen zu halten, aber ich finde es nicht heraus, dies zu tun. Irgendeine Ahnung?
EIN MutationObserver ist wie ein Ereignis-Listener: Sie können ihn an jedes DOM-Element anhängen, um auf Änderungen zu warten:
var observer = new MutationObserver(function (mutationRecords) {
console.log("change detected");
});
Dem Callback wird ein Array von übergeben MutationRecords, die verschiedene Listen von hinzugefügten/gelöschten/geänderten Knoten enthalten.
Dann hängen wir den Beobachter an einen beliebigen Knoten an:
observer.observe(document.body, {childList: true});
// second argument is a config: in this case, only fire the callback when nodes are added or removed
Hier ist eine weitere SO-Frage zum Erkennen von Änderungen am DOM: Änderungen im DOM erkennen
Ausschnitt:
document.querySelector("button").addEventListener("click", function () {
document.body.appendChild(document.createElement("span"));
});
var observer = new MutationObserver(function (m) {
if (m[0].addedNodes[0].nodeName === "SPAN")
document.querySelector("div").innerHTML += "Change Detected<br>";
});
observer.observe(document.body, {childList: true});
<button>Click</button>
<div></div>
Ich würde davon abraten, MutationObserver zu verwenden. Dieser Ansatz hat viele Nachteile: Er verlangsamt das Laden von Seiten und hat eine schlechte Browserunterstützung. Es gibt Situationen, in denen dies der einzige Ansatz ist, um das vorliegende Problem zu lösen.
Ein besserer Ansatz ist die Verwendung von onload DOM-Ereignis. Dieses Ereignis funktioniert mit Tags wie iframe und img. Für andere Tags ist dies der Pseudocode, von dem Sie sich inspirieren lassen können:
<body>
<script>
function divLoaded(event){
alert(event.target.previousSibling.previousSibling.id);
}
</script>
<div id="element_to_watch">This is an example div to watch it's loading</div>
<iframe style="display: none; width: 0; height: 0" onload="divLoaded(event)"/>
</body>
HINWEIS: Der Trick besteht darin, nach jedem Element, das Sie auf das Laden überwachen möchten, ein iframe- oder img-Element anzuhängen.
Wenn Sie diesem Ansatz folgen, kann diese spezielle Frage auf viele Arten gelöst werden, z. B. können Sie das Laden des Skript-Tags beobachten und dann mithilfe von Javascript dynamisch ein anderes Skript laden.
– Shyam Swaroop
27. Februar 2020 um 19:49 Uhr
Hier ist eine in ClojureScript geschriebene Funktion, die eine Funktion aufruft, wenn eine Bedingung erfüllt ist.
Erweiterung der Lösung von @i-wrestled-a-bear-once. Mit diesem js-Code können wir das Popup auch deaktivieren, wenn die Zielkomponente nicht mehr im DOM vorhanden ist.
Es kann für Fälle verwendet werden, in denen Sie nach einer Dateieingabe für eine Anfrage fragen und die Datei nicht anzeigen möchten, nachdem er mit der Anfrage fertig ist.
// Call this to run a method when a element removed from DOM
function waitForElementToUnLoad(querySelector) {
const startTime = new Date().getTime();
return new Promise((resolve, reject)=>{
const timer = setInterval(()=>{
const now = new Date().getTime();
if(!document.querySelector(querySelector)) {
clearInterval(timer);
resolve();
}
}, 1000);
});
}
// Call this to run a method when a element added to DOM, set timeout if required.
// Checks every second.
function waitForElementToLoad(querySelector, timeout=0) {
const startTime = new Date().getTime();
return new Promise((resolve, reject)=>{
const timer = setInterval(()=>{
const now = new Date().getTime();
if(document.querySelector(querySelector)){
clearInterval(timer);
resolve();
}else if(timeout && now - startTime >= timeout){
clearInterval(timer);
reject();
}
}, 1000);
});
}
// Removing onclose popup if no file is uploaded.
function executeUnloadPromise(id) {
waitForElementToUnLoad(id).then(function(){
window.onbeforeunload = null;
executeLoadPromise("#uploaded-file");
});
}
// Adding onclose popup if a file is uploaded.
function executeLoadPromise(id) {
waitForElementToLoad(id).then(function(){
window.onbeforeunload = function(event) {
return "Are you sure you want to leave?";
}
executeUnloadPromise("#uploaded-file");
});
}
executeLoadPromise("#uploaded-file");
Würde mich über Vorschläge freuen, wie ich das besser machen kann.
14312300cookie-checkWie kann überprüft werden, ob ein Element auf einer Seite geladen wurde, bevor ein Skript ausgeführt wird?yes
Schreiben Sie ein Skript, um Ihr Skript am Ende der Seite anzuhängen, damit es danach geladen wird
– Johnny 5
18. Januar 2016 um 20:49 Uhr
If ( $('.element').length )
– adeneo
18. Januar 2016 um 20:53 Uhr
Verwenden Sie den Code, der das Element hinzufügt, um Ihren Code auszuführen, der sich auf dieses Element auswirken würde. Benötigen Sie ein besseres Verständnis des Problems, um qualitativ hochwertigere Antworten zu erhalten und weniger zu raten
– charlietfl
18. Januar 2016 um 20:56 Uhr
@ johnny5, das sich nicht damit befasst, ob ein dynamisch hinzugefügtes Element vorhanden ist oder nicht
– charlietfl
18. Januar 2016 um 21:00 Uhr