Bagaimana cara memanggil fungsi setelah jQuery .append
selesai?
Berikut contohnya:
$("#root").append(child, function(){
// Action after append is completly done
});
Masalahnya: Saat struktur DOM yang kompleks ditambahkan, perhitungan ukuran baru dari elemen root dalam callback fungsi penambahan menjadi salah. Asumsinya adalah bahwa DOM masih belum dimuat sepenuhnya, hanya anak pertama dari DOM kompleks yang ditambahkan yang.
append()
hanya membutuhkan sedikit waktu.Jawaban:
Anda memiliki banyak jawaban yang valid di sini, tetapi tidak ada yang benar-benar memberi tahu Anda mengapa ini berfungsi seperti itu.
Dalam JavaScript, perintah dijalankan satu per satu, secara sinkron sesuai urutannya, kecuali Anda secara eksplisit memberi tahu mereka untuk menjadi asinkron dengan menggunakan waktu tunggu atau interval.
Ini berarti bahwa
.append
metode Anda akan dieksekusi dan tidak ada yang lain (dengan mengabaikan potensi waktu tunggu atau interval yang mungkin ada) yang akan dijalankan hingga metode tersebut menyelesaikan tugasnya.Untuk meringkas, tidak perlu callback karena
.append
akan dijalankan secara sinkron.sumber
Meskipun Marcus Ekwall benar tentang sinkronisitas append, saya juga menemukan bahwa dalam situasi yang aneh terkadang DOM tidak dirender sepenuhnya oleh browser saat baris kode berikutnya dijalankan.
Dalam skenario ini, solusi shadowdiver berada di jalur yang benar - dengan menggunakan .ready - namun jauh lebih rapi untuk merangkai panggilan ke lampiran asli Anda.
$('#root') .append(html) .ready(function () { // enter code here });
sumber
Saya punya masalah yang persis sama dengan penghitungan ulang ukuran dan setelah berjam-jam sakit kepala, saya harus tidak setuju dengan
.append()
berperilaku sangat sinkron. Setidaknya di Google Chrome. Lihat kode berikut.var input = $( '<input />' ); input.append( arbitraryElement ); input.css( 'padding-left' );
Properti padding-left diambil dengan benar di Firefox tapi kosong di Chrome. Seperti semua properti CSS lainnya, saya kira. Setelah beberapa percobaan saya harus puas membungkus 'getter' CSS
setTimeout()
dengan penundaan 10 ms yang saya tahu JELEK sekali tapi satu-satunya yang bekerja di Chrome. Jika ada di antara Anda yang memiliki ide bagaimana mengatasi masalah ini dengan lebih baik, saya akan sangat berterima kasih.sumber
.ready()
solusi yang jauh lebih baik dan lebih elegan.Saya terkejut dengan semua jawaban di sini ...
Coba ini:
window.setTimeout(function() { /* your stuff */ }, 0);
Catat 0 batas waktu. Ini bukan angka yang sewenang-wenang ... seperti yang saya mengerti (meskipun pemahaman saya mungkin agak goyah), ada dua antrian acara javascript - satu untuk acara makro dan satu untuk acara mikro. Antrean cakupan "lebih besar" menampung tugas-tugas yang memperbarui UI (dan DOM), sedangkan antrian mikro melakukan operasi jenis tugas cepat.
Sadari juga bahwa menyetel waktu tunggu tidak menjamin bahwa kode bekerja tepat pada nilai yang ditentukan. Apa yang dilakukan ini pada dasarnya adalah menempatkan fungsi ke antrean yang lebih tinggi (yang menangani UI / DOM), dan tidak menjalankannya sebelum waktu yang ditentukan.
Ini berarti bahwa menyetel waktu tunggu 0 akan menempatkannya di bagian UI / DOM dari antrean peristiwa javascript, untuk dijalankan pada kesempatan berikutnya yang memungkinkan.
Ini berarti DOM diperbarui dengan semua item antrian sebelumnya (seperti dimasukkan lewat
$.append(...);
, dan saat kode Anda berjalan, DOM tersedia sepenuhnya.(ps - Saya mempelajarinya dari Secrects of the JavaScript Ninja - sebuah buku yang sangat bagus: https://www.manning.com/books/secrets-of-the-javascript-ninja )
sumber
setTimeout()
selama bertahun-tahun tanpa mengetahui alasannya. Terima kasih untuk penjelasannya!Saya memiliki varian lain yang mungkin berguna untuk seseorang:
$('<img src="http://example.com/someresource.jpg">').load(function() { $('#login').submit(); }).appendTo("body");
sumber
...on('load', function(){ ...
lihat di sini: stackoverflow.com/a/37751413/2008111Saya menemukan masalah yang sama dan telah menemukan solusi sederhana. Tambahkan setelah memanggil fungsi append dokumen siap.
$("#root").append(child); $(document).ready(function () { // Action after append is completly done });
sumber
Menggunakan
MutationObserver
can bertindak seperti callback untukappend
metode jQuery :Saya sudah menjelaskannya di pertanyaan lain , dan kali ini saya hanya akan memberikan contoh untuk browser modern:
// Somewhere in your app: var observeDOM = (() => { var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; return function(obj, callback){ if( MutationObserver ){ // define a new observer var obs = new MutationObserver(function(mutations, observer){ if( mutations[0].addedNodes.length || mutations[0].removedNodes.length ) callback(mutations); }); // have the observer observe foo for changes in children obs.observe( obj, { childList:true, subtree:true }); return obs; } } })(); ////////////////// // Your code: // setup the DOM observer (on the appended content's parent) before appending anything observeDOM( document.body, ()=>{ // something was added/removed }).disconnect(); // don't listen to any more changes // append something $('body').append('<p>foo</p>');
sumber
Saya pikir ini dijawab dengan baik tetapi ini sedikit lebih spesifik untuk menangani "subChild_with_SIZE" (jika itu berasal dari induk, tetapi Anda dapat menyesuaikannya dari tempatnya)
$("#root").append( $('<div />',{ 'id': 'child' }) ) .children() .last() .each(function() { $(this).append( $('<div />',{ 'id': $(this).parent().width() }) ); });
sumber
$.when($('#root').append(child)).then(anotherMethod());
sumber
$.when
hanya bekerja untuk objek yang mengembalikan objek janjianotherMethod()
langsung memanggil .. Ini tidak diteruskan sebagai panggilan balik.fungsi penambahan Jquery mengembalikan objek jQuery sehingga Anda bisa memberi tag pada metode di akhir
$("#root").append(child).anotherJqueryMethod();
sumber
Untuk gambar dan sumber lain, Anda dapat menggunakan itu:
$(el).one('load', function(){ // completed }).each(function() { if (this.complete) $(this).load(); });
sumber
Cara terbersih adalah melakukannya selangkah demi selangkah. Gunakan setiap fungsi untuk mengulang setiap elemen. Segera setelah elemen itu ditambahkan, teruskan ke fungsi selanjutnya untuk memproses elemen itu.
function processAppended(el){ //process appended element } var remove = '<a href="#">remove</a>' ; $('li').each(function(){ $(this).append(remove); processAppended(this); });
sumber
Saya mengalami masalah ini saat mengkode HTML5 untuk perangkat seluler. Beberapa kombinasi browser / perangkat menyebabkan kesalahan karena metode .append () tidak mencerminkan perubahan di DOM secara langsung (menyebabkan JS gagal).
Solusi cepat dan kotor untuk situasi ini adalah:
var appint = setInterval(function(){ if ( $('#foobar').length > 0 ) { //now you can be sure append is ready //$('#foobar').remove(); if elem is just for checking //clearInterval(appint) } }, 100); $(body).append('<div>...</div><div id="foobar"></div>');
sumber
Ya, Anda dapat menambahkan fungsi panggilan balik ke setiap penyisipan DOM:
$myDiv.append( function(index_myDiv, HTML_myDiv){ //.... return child })
Periksa dokumentasi JQuery: http://api.jquery.com/append/
Dan inilah contoh praktis dan serupa: http://www.w3schools.com/jquery/ tryit.asp? filename = tryjquery_html_prepend_func
sumber
.prepend()
metode dengan: $ ("p"). Prepend (function (n, pHTML) {return "<b> Elemen p ini </b> (\" <i > "+ pHTML +" </i> \ ") <b> memiliki indeks" + n + "</b>.";Saya mengalami masalah serupa baru-baru ini. Solusi bagi saya adalah membuat ulang colletion. Izinkan saya mencoba menunjukkan:
var $element = $(selector); $element.append(content); // This Doesn't work, because $element still contains old structure: $element.fooBar(); // This should work: the collection is re-created with the new content: $(selector).fooBar();
Semoga ini membantu!
sumber
Di jquery, Anda bisa menggunakan setelah menambahkan
$(function(){ //code that needs to be executed when DOM is ready, after manipulation });
$ () memanggil fungsi yang mendaftarkan callback siap DOM (jika fungsi diteruskan ke sana) atau mengembalikan elemen dari DOM (jika string atau elemen pemilih diteruskan ke sana)
Anda dapat menemukan lebih banyak di sini
perbedaan antara $ dan $ () di jQuery
http://api.jquery.com/ready/
sumber
Saya tahu ini bukan solusi terbaik, tetapi praktik terbaik:
$("#root").append(child); setTimeout(function(){ // Action after append },100);
sumber
$('#root').append(child); // do your work here
Append tidak memiliki callback, dan ini adalah kode yang dijalankan secara sinkron - tidak ada risiko TIDAK dilakukan
sumber
$('#root').append(child).anotherMethod();
sumber