Bagaimana cara menunggu sampai ada elemen?

237

Saya sedang mengerjakan Ekstensi di Chrome, dan saya bertanya-tanya: apa cara terbaik untuk mengetahui kapan suatu elemen muncul? Menggunakan javascript biasa, dengan interval yang memeriksa hingga elemen ada, atau apakah jQuery punya cara mudah untuk melakukan ini?

mattsven
sumber
1
Sepertinya setiap opsi di sini hari ini (termasuk dari komentar) sudah kedaluwarsa atau tidak lengkap. Mereka tidak menganggap input luar biasa @ hughsk sepenuhnya, argumen kompatibilitas. Sementara itu saya akan merekomendasikan hanya menggunakan pembaruan Brandon pada jawaban Ryan untuk kesederhanaan umum dan lebih sedikit risiko overhead, saya kira.
cregox
4
MutationObserver> DOM Mutation Events> setTimeout.
mattsven
2
Bukan dari tempat saya berdiri. setTimeoutkompatibel, mudah diimplementasikan, mudah dirawat, dan memiliki overhead yang dapat diabaikan.
cregox
setTimeout+ jQuerykurang dari ideal menurut saya karena dua alasan: 1.) jQuery mengasapi 2.) Anda tidak perlu secara manual menanyakan DOM untuk elemen, peristiwa mengalahkan kecepatan itu dengan mudah, 3.) itu akan selalu lebih lambat daripada yang asli penerapan. Jika Anda perlu melakukan apa pun berdasarkan kehadiran elemen yang cukup cepat, terutama jika pengalaman pengguna yang mulus adalah tujuan Anda, itu lebih rendah.
mattsven
3
Ada 3 jenis orang: mereka yang bisa menghitung dan mereka yang tidak bisa. ; P
cregox

Jawaban:

149

DOMNodeInsertedsedang tidak digunakan lagi, bersama dengan peristiwa mutasi DOM lainnya, karena masalah kinerja - pendekatan yang disarankan adalah menggunakan MutationObserver untuk menonton DOM. Ini hanya didukung di browser yang lebih baru, jadi Anda harus kembali DOMNodeInsertedketika MutationObservertidak tersedia.

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if (!mutation.addedNodes) return

    for (var i = 0; i < mutation.addedNodes.length; i++) {
      // do things to your newly added nodes here
      var node = mutation.addedNodes[i]
    }
  })
})

observer.observe(document.body, {
    childList: true
  , subtree: true
  , attributes: false
  , characterData: false
})

// stop watching using:
observer.disconnect()
hughsk
sumber
50
Saya selalu menemukan api MutationObserver agak rumit jadi saya telah membangun sebuah perpustakaan, arrived.js , untuk menyediakan api yang lebih sederhana untuk mendengarkan pembuatan / penghapusan elemen.
Uzair Farooq
15
Saya sarankan menggunakan @UzairFarooq library yang sangat bagus github.com/uzairfarooq/arrive
Dennis
3
Dua hal yang perlu diperhatikan: (1) Akan lebih baik untuk dilakukan if (mutation.addedNodes.length)karena if (mutation.addedNodes)masih akan mengembalikan true walaupun array kosong. (2) Anda tidak dapat melakukan mutation.addedNodes.forEach()karena ditambahkanNodes adalah nodeList dan Anda tidak dapat mengulangi melalui nodeList dengan forEach. Untuk solusi untuk ini, lihat toddmotto.com/ditch-the-array-foreach-call-nodelist-hack
thdoan
3
Bisakah Anda memberi contoh bagaimana seseorang akan menggunakan ini? Tidak yakin di mana harus meletakkan pemilih jquery atau kode yang ingin saya jalankan ketika elemen DOM ada.
Superdooperhero
1
@Superdooperhero Saya membuat jawaban dengan contoh mudah. Periksa. stackoverflow.com/a/57395241/6542186
SilverSurfer
113

Saya mengalami masalah yang sama, jadi saya melanjutkan dan menulis sebuah plugin untuk itu.

$(selector).waitUntilExists(function);

Kode:

;(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));
Ryan Lester
sumber
5
Terima kasih atas pluginnya. Saya bercabang dan memperbaikinya sedikit. Silakan mengambil apa pun yang Anda inginkan dari pembaruan saya. Saya memiliki beberapa perbaikan lagi yang direncanakan, masih: plugin yang diperbarui
Brandon Belvin
8
akan menyenangkan tanpa jquery dep juga ...;)
knutole
4
mungkin Anda harus menyebutkan cara kerjanya: berfungsi dengan menanyakan setiap 500 ms jika elemen ada (menggunakan a window.setInterval). Saya tidak tahu apakah MutationObserverjawabannya bekerja dengan pemungutan suara juga ...
olahraga
2
Itu tidak berfungsi dengan baik jika elemen sudah ada di halaman. Ini adalah versi yang tepat dari fungsi ini: gist.github.com/PizzaBrandon/5709010
Roland Soós
2
Bisakah Anda jelaskan apa gunanya ;di awal fungsi ( ;(function ($, window) {)?
mrid
76

Berikut adalah fungsi inti JavaScript untuk menunggu tampilan elemen.

Parameter:

  1. selector: Fungsi ini mencari elemen $ {selector}
  2. time: Fungsi ini memeriksa apakah elemen ini ada setiap $ {waktu} milidetik.

    function waitForElementToDisplay(selector, time) {
            if(document.querySelector(selector)!=null) {
                alert("The element is displayed, you can put your code instead of this alert.")
                return;
            }
            else {
                setTimeout(function() {
                    waitForElementToDisplay(selector, time);
                }, time);
            }
        }
    

Sebagai contoh, pengaturan selector="#div1"dan time=5000akan mencari tag HTML yang id="div1"setiap 5.000 milidetik.

Etienne Tonnelier
sumber
Bagus! Bisakah Anda menulis ini sehingga pemilih mana pun dapat diterima?
mattsven
Saya ragu saya bisa melakukannya .. Tapi tolong lihat posting ini untuk mendapatkan getElementByXpath: stackoverflow.com/questions/10596417/…
Etienne Tonnelier
1
Bagaimana dengan querySelector? developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
mattsven
1
Bisakah Anda menulisnya menggunakan pengamat mutasi?
SuperUberDuper
atau bisakah Anda menulis ulang ini untuk menggunakan janji?
SuperUberDuper
25

Anda dapat mendengarkan DOMNodeInsertedatau DOMSubtreeModifiedacara yang memanas kapan saja elemen baru ditambahkan ke DOM.

Ada juga plugin LiveQuery jQuery yang akan mendeteksi ketika elemen baru dibuat:

$("#future_element").livequery(function(){
    //element created
});
serg
sumber
1
Plugin yang sangat bagus! Apakah ada fungsi seperti itu di jquery secara langsung? Saya ingin tahu bahwa tidak ada fitur yang ada untuk melakukan itu. Dan jika ini adalah THE plugin, silakan pilih jawaban ini;) Bagi saya, itu berfungsi dengan baik. Terima kasih banyak.
Samuel
1
Catatan IE 9 mengimplementasikan DOMNodeInserted tetapi memiliki bug utama di mana itu tidak akan menyala ketika Anda menambahkan elemen untuk waktu itu, yang sebagian besar waktu ketika Anda ingin menggunakannya. Detailnya ada di: help.dottoro.com/ljmcxjla.php
mikemaccana
23

Saya menggunakan pendekatan ini untuk menunggu elemen muncul sehingga saya dapat menjalankan fungsi lain setelah itu.

Katakanlah doTheRestOfTheStuff(parameters)fungsi hanya dipanggil setelah elemen dengan ID the_Element_IDmuncul atau selesai memuat, kita dapat menggunakan,

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

Anda dapat melakukan

$('#yourelement').ready(function() {

});

Harap dicatat bahwa ini hanya akan berfungsi jika elemen ada di DOM ketika diminta dari server. Jika elemen ditambahkan secara dinamis melalui JavaScript, elemen itu tidak akan berfungsi dan Anda mungkin perlu melihat jawaban lainnya.

Splynx
sumber
7
The .ready()karya fungsi untuk sebagian apa-apa (jika tidak apa-apa), tidak hanya document. Itu tidak akan bekerja dengan elemen yang dibuat secara dinamis, bahkan pada .live().
Richard Neil Ilagan
7
@Bery, seperti yang ditunjukkan Richard, ini hanya berfungsi untuk elemen yang sudah ada dalam HTML saat pertama kali diminta dari server. Jika Javascript digunakan untuk menambahkan elemen secara dinamis ke DOM, itu tidak berfungsi.
Chandranshu
6
@ Sam, bisakah Anda menjelaskan cara melampirkannya ke referensi elemen dalam memori?
Vikas Singhal
3
Jawaban ini salah. Apa yang sebenarnya Anda periksa di sini adalah $(document).ready()elemen biasa , bukan elemen yang Anda pikir akan berlaku juga. Begitulah cara pendengar khusus ini bekerja. Contoh
Shikkediel
1
Penggunaan ini tidak disarankan menurut api.jquery.com/ready
splintor
14

Saya pikir masih belum ada jawaban di sini dengan contoh kerja yang mudah dan mudah dibaca. Gunakan MutationObserver interface untuk mendeteksi perubahan DOM, seperti ini:

var observer = new MutationObserver(function(mutations) {
    if ($("p").length) {
        console.log("Exist, lets do something");
        observer.disconnect(); 
        //We can disconnect observer once the element exist if we dont want observe more changes in the DOM
    }
});

// Start observing
observer.observe(document.body, { //document.body is node target to observe
    childList: true, //This is a must have for the observer with subtree
    subtree: true //Set to true if changes must also be observed in descendants.
});
            
$(document).ready(function() {
    $("button").on("click", function() {
        $("p").remove();
        setTimeout(function() {
            $("#newContent").append("<p>New element</p>");
        }, 2000);
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button>New content</button>
<div id="newContent"></div>

Catatan: Spanish Mozilla docs about MutationObserverlebih detail jika Anda menginginkan informasi lebih lanjut.

Peselancar perak
sumber
2
Pertimbangkan untuk memberikan komentar yang menjelaskan alasan downvote, sehingga saya dapat meningkatkan jawaban saya. Terima kasih.
SilverSurfer
12

Cukup tambahkan pemilih yang Anda inginkan. Setelah elemen ditemukan, Anda dapat memiliki akses ke dalam fungsi panggilan balik.

const waitUntilElementExists = (selector, callback) => {
const el = document.querySelector(selector);

if (el){
    return callback(el);
}

setTimeout(() => waitUntilElementExists(selector, callback), 500);
}

waitUntilElementExists('.wait-for-me', (el) => console.log(el));
Diego Fortes
sumber
2
PossessWithin setuju, ini adalah solusi yang sangat bersih dan berfungsi untuk saya.
jstafford
3
Jawaban ini berfungsi pada IE8-10 dan juga peramban modern. Masalah utama adalah bahwa ia akan terus berjalan jika elemen tidak ada - jadi yang terbaik kapan Anda yakin elemen tersebut akan ada di sana. Kalau tidak, Anda bisa menambahkan penghitung.
Untuk Nama
1
Bekerja dengan sempurna untuk saya
James Stewart
1
Bekerja seperti pesona !!
Aman
1
Mereka serupa, tidak identik. Selain itu, banyak orang melakukan hal yang sama. Terakhir, saya mengkodekan solusi ini sendiri. Itu adalah alasan yang buruk, namun, jika itu memang benar, saya akan menghargai komentar yang memberi tahu saya. Jawabannya memecahkan masalah OP dan tidak memiliki motif yang jelas untuk diturunkan.
Diego Fortes
11

Untuk pendekatan sederhana menggunakan jQuery, saya menemukan ini berfungsi dengan baik:

  // Wait for element to exist.
  function elementLoaded(el, cb) {
    if ($(el).length) {
      // Element is now loaded.
      cb($(el));
    } else {
      // Repeat every 500ms.
      setTimeout(function() {
        elementLoaded(el, cb)
      }, 500);
    }
  };

  elementLoaded('.element-selector', function(el) {
    // Element is ready to use.
    el.click(function() {
      alert("You just clicked a dynamically inserted element");
    });
  });

Di sini kita cukup memeriksa setiap 500ms untuk melihat apakah elemen tersebut dimuat, ketika itu, kita dapat menggunakannya.

Ini sangat berguna untuk menambahkan penangan klik ke elemen yang telah ditambahkan secara dinamis ke dokumen.

Hedley Smith
sumber
8

Bagaimana dengan pustaka insertionQuery ?

insertionQuery menggunakan callback Animasi CSS yang dilampirkan pada pemilih yang ditentukan untuk menjalankan callback ketika sebuah elemen dibuat. Metode ini memungkinkan panggilan balik dijalankan setiap kali elemen dibuat, bukan hanya pertama kali.

Dari github:

Cara non-dom-event untuk menangkap node yang muncul. Dan itu menggunakan penyeleksi.

Ini bukan hanya untuk dukungan browser yang lebih luas, Ini bisa lebih baik daripada DOMMutationObserver untuk hal-hal tertentu.

Mengapa?

  • Karena Acara DOM memperlambat browser dan insertionQuery tidak
  • Karena DOM Mutation Observer memiliki lebih sedikit dukungan browser daripada insertionQuery
  • Karena dengan insertionQuery Anda dapat memfilter perubahan DOM menggunakan penyeleksi tanpa overhead kinerja!

Dukungan luas!

IE10 + dan sebagian besar hal lain (termasuk seluler)

b3wii
sumber
7

Inilah fungsi yang bertindak sebagai pembungkus tipis di sekitar MutationObserver. Satu-satunya persyaratan adalah bahwa browser mendukung MutationObserver; tidak ada ketergantungan pada JQuery. Jalankan cuplikan di bawah untuk melihat contoh yang berfungsi.

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 = $("<div><span class='foo'>Outer</span></div>");
  $outerContent.append(newNode);
});
$("#addInner").on("click", function() {
  var newNode = $("<div><span class='foo'>Inner</span></div>");
  $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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Create some mutations</h2>
<div id="main">
  <button id="addOuter">Add outer node</button>
  <button id="addInner">Add inner node</button>
  <div class="content" id="outerContent">
    <div class="content" id="innerContent"></div>
  </div>
</div>
<h2>Log</h2>
<div id="log"></div>

Ivan Karajas
sumber
6

Inilah solusi Pengembalian Janji dalam vanila Javascript (tidak ada panggilan balik yang berantakan). Secara default ia memeriksa setiap 200 ms.

function waitFor(selector) {
    return new Promise(function (res, rej) {
        waitForElementToDisplay(selector, 200);
        function waitForElementToDisplay(selector, time) {
            if (document.querySelector(selector) != null) {
                res(document.querySelector(selector));
            }
            else {
                setTimeout(function () {
                    waitForElementToDisplay(selector, time);
                }, time);
            }
        }
    });
}
blaster
sumber
5

Inilah fungsi Javascript murni yang memungkinkan Anda menunggu apa pun. Atur interval lebih lama untuk mengurangi sumber daya CPU.

/**
 * @brief Wait for something to be ready before triggering a timeout
 * @param {callback} isready Function which returns true when the thing we're waiting for has happened
 * @param {callback} success Function to call when the thing is ready
 * @param {callback} error Function to call if we time out before the event becomes ready
 * @param {int} count Number of times to retry the timeout (default 300 or 6s)
 * @param {int} interval Number of milliseconds to wait between attempts (default 20ms)
 */
function waitUntil(isready, success, error, count, interval){
    if (count === undefined) {
        count = 300;
    }
    if (interval === undefined) {
        interval = 20;
    }
    if (isready()) {
        success();
        return;
    }
    // The call back isn't ready. We need to wait for it
    setTimeout(function(){
        if (!count) {
            // We have run out of retries
            if (error !== undefined) {
                error();
            }
        } else {
            // Try again
            waitUntil(isready, success, error, count -1, interval);
        }
    }, interval);
}

Untuk memanggil ini, misalnya di jQuery, gunakan sesuatu seperti:

waitUntil(function(){
    return $('#myelement').length > 0;
}, function(){
    alert("myelement now exists");
}, function(){
    alert("I'm bored. I give up.");
});
xgretsch
sumber
3

Solusi yang mengembalikan Promisedan memungkinkan untuk menggunakan batas waktu (IE 11+ yang kompatibel).

Untuk satu elemen (tipe Elemen):

"use strict";

function waitUntilElementLoaded(selector) {
    var timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;

    var start = performance.now();
    var now = 0;

    return new Promise(function (resolve, reject) {
        var interval = setInterval(function () {
            var element = document.querySelector(selector);

            if (element instanceof Element) {
                clearInterval(interval);

                resolve();
            }

            now = performance.now();

            if (now - start >= timeout) {
                reject("Could not find the element " + selector + " within " + timeout + " ms");
            }
        }, 100);
    });
}

Untuk beberapa elemen (ketik NodeList):

"use strict";

function waitUntilElementsLoaded(selector) {
    var timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;

    var start = performance.now();
    var now = 0;

    return new Promise(function (resolve, reject) {
        var interval = setInterval(function () {
            var elements = document.querySelectorAll(selector);

            if (elements instanceof NodeList) {
                clearInterval(interval);

                resolve(elements);
            }

            now = performance.now();

            if (now - start >= timeout) {
                reject("Could not find elements " + selector + " within " + timeout + " ms");
            }
        }, 100);
    });
}

Contoh:

waitUntilElementLoaded('#message', 800).then(function(element) {
    // element found and available

    element.innerHTML = '...';
}).catch(function() {
    // element not found within 800 milliseconds
});

waitUntilElementsLoaded('.message', 10000).then(function(elements) {
    for(const element of elements) {
        // ....
    }
}).catch(function(error) {
    // elements not found withing 10 seconds
});

Berfungsi untuk daftar elemen dan elemen tunggal.

Anwar
sumber
1
Solusi favorit saya! Mengapa memeriksa element instanceof HTMLElement? Bisakah itu menjadi sesuatu selain nullatau HTMLElement?
Leeroy
1
Anda meningkatkan poin yang menarik. Seharusnya saya membuatnya lebih luas dengan menggunakan Elementsebagai gantinya (diperbaiki). Saya hanya melakukan pemeriksaan karena saya ingin memastikan variabel tersebut elementmemiliki properti innerHTMLseperti yang dinyatakan oleh dokumentasi Elemen MDN . Jangan ragu untuk menghapusnya jika Anda tidak peduli!
Anwar
2

Contoh yang lebih bersih menggunakan MutationObserver:

new MutationObserver( mutation => {
    if (!mutation.addedNodes) return
    mutation.addedNodes.forEach( node => {
        // do stuff with node
    })
})
Zaz
sumber
2

Ini adalah solusi sederhana bagi mereka yang terbiasa dengan janji dan tidak ingin menggunakan lib atau timer pihak ketiga.

Saya telah menggunakannya dalam proyek saya untuk sementara waktu

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

Untuk menggunakannya:

waitForElm('.some-class').then(elm => console.log(elm.textContent));

atau dengan async / menunggu

const elm = await waitForElm('.some-classs')
Yong Wang
sumber
Ini rapi! Bagian kerennya adalah Anda bisa menggunakannya dengan async/ awaitjuga. Anda juga dapat memeras kinerja lebih banyak dengan melakukanmutations.addedNodes.find(node => node.matchesSelector("..."))
mattsven
@ Mattsven Poin bagus! Memeriksa hanya simpul dalam mutasi yang lebih berkinerja daripada melakukan document.querySelector.
Yong Wang
Silakan benar kesalahan ejaan, watiForElm untuk waitForElm
dalvir
1

Jika Anda ingin berhenti mencari setelah beberapa saat (batas waktu) maka jQuery berikut ini akan berfungsi. Ini akan habis setelah 10 detik. Saya perlu menggunakan kode ini daripada JS murni karena saya perlu memilih input melalui nama dan mengalami kesulitan menerapkan beberapa solusi lain.

 // Wait for element to exist.

    function imageLoaded(el, cb,time) {

        if ($(el).length) {
            // Element is now loaded.

            cb($(el));

            var imageInput =  $('input[name=product\\[image_location\\]]');
            console.log(imageInput);

        } else if(time < 10000) {
            // Repeat every 500ms.
            setTimeout(function() {
               time = time+500;

                imageLoaded(el, cb, time)
            }, 500);
        }
    };

    var time = 500;

    imageLoaded('input[name=product\\[image_location\\]]', function(el) {

     //do stuff here 

     },time);
S-Thomas
sumber
0

Saya biasanya menggunakan potongan ini untuk Pengelola Tag:

<script>
(function exists() {
  if (!document.querySelector('<selector>')) {
    return setTimeout(exists);
  }
  // code when element exists
})();  
</script>
Alejo JM
sumber
0

jika Anda memiliki perubahan dom async, fungsi ini memeriksa (dengan batas waktu dalam detik) untuk elemen DOM, itu tidak akan berat untuk DOM dan berdasarkan janjinya :)

function getElement(selector, i = 5) {
  return new Promise(async (resolve, reject) => {
    if(i <= 0) return reject(`${selector} not found`);
    const elements = document.querySelectorAll(selector);
    if(elements.length) return resolve(elements);
    return setTimeout(async () => await getElement(selector, i-1), 1000);
  })
}

// Now call it with your selector

try {
  element = await getElement('.woohoo');
} catch(e) { // catch the e }

//OR

getElement('.woohoo', 5)
.then(element => { // do somthing with the elements })
.catch(e => { // catch the error });
Meni Edri
sumber