Baru -baru ini saya menulis kerangka kerja JavaScript. Saya baru saja merangkum acara DomContentloaded, dan saya sedikit bersemangat. Saya mencatat tentang prinsip -prinsip dan masalah kompatibilitas yang dihadapi selama proses pengembangan, untuk menghindari lupa di mana -mana.
Saat kami menulis kode JS, kami biasanya menambahkan acara Window.onload, terutama untuk menggunakan GetElementById, GetElementsByTagname dan metode lain untuk memilih elemen DOM untuk operasi setelah DOM dimuat. Namun, Window.load akan menunggu sampai DOM, skrip, CSS dimuat, dan semua sumber daya dalam gambar atau bahkan iframe dipicu. Dalam banyak kasus, halaman web memiliki lebih banyak gambar dan lebih besar. Butuh waktu lama untuk memuat gambar, dan jelas sudah terlambat untuk mengeksekusi JS, yang sering akan mempengaruhi pengalaman pengguna.
Banyak kerangka kerja JS memiliki fungsi dokumen. Fungsi, seperti metode $ (dokumen) .ready (), yang dapat menjalankan kode JS segera setelah DOM dimuat, sehingga gambar dapat dimuat secara perlahan.
Inti dari dokumen. Firefox, Chrome, Opera, Safari, dan IE9+ semuanya dapat menggunakan AddEventListener ('domContentloaded', fn, false) untuk pengikatan acara. IE6 ~ 8 tidak mendukung acara DomContentloaded, sehingga pemrosesan kompatibilitas harus dilakukan untuk IE6 ~ 8.
Informasi tersebut mengatakan bahwa IE6 ~ 8 dapat menggunakan acara dokumen. Jika iframe tertanam di halaman, dokumen. Pada saat ini, iframe menjadi pengguna utama yang memakan waktu. Tetapi setelah pengujian, bahkan jika tidak ada iframe di halaman, ketika ReadyState sama dengan selesai, acara Onload sebenarnya dipicu alih -alih acara DOMContentloaded, yang mengejutkan untuk titik ini.
Untungnya, IE memiliki metode doscroll yang unik. Ketika dom halaman tidak dimuat, kesalahan akan dilaporkan ketika metode doscroll dipanggil. Sebaliknya, selama doscroll dipanggil pada interval sampai tidak ada kesalahan yang dilaporkan, itu berarti bahwa dom halaman telah dimuat. Metode ini valid terlepas dari apakah konten dalam gambar dan iframe telah dimuat.
Jika beberapa file JS terikat pada acara dokumen.
Di atas adalah masalah prinsip dan kompatibilitas dokumen. Berikut ini adalah paragraf kode contoh. Untuk memfasilitasi pemahaman tentang proses eksekusi, proses eksekusi ditulis dalam komentar menggunakan mode enkapsulasi fungsi. Jika ada ketidaksesuaian, tolong beri saya beberapa saran.
Salinan kode adalah sebagai berikut:
// Simpan antrian acara Domready
EventQueue = [];
// menilai apakah DOM telah dimuat
isready = false;
// menilai apakah domready terikat
isBind = false;
/*Jalankan domready ()
*
*@param {function}
*@Execute mendorong event handler ke antrian acara dan mengikat domcontentloaded
* Jika pemuatan DOM telah selesai, segera jalankan
*@penelepon
*/
function domready (fn) {
if (isready) {
fn.call (jendela);
}
kalau tidak{
Eventqueue.push (fn);
};
bindready ();
};
/*mengikat acara domready
*
*@param null
*@Jalankan browser modern mengikat domContentloaded melalui addevListener, termasuk IE9+
IE6-8 menentukan apakah DOM telah dimuat dengan menilai doscroll
*@caller domready ()
*/
function bindReady () {
if (isready) kembali;
if (isBind) kembali;
isBind = true;
if (window.addeventListener) {
document.addeventListener ('domcontentloaded', execfn, false);
}
lain if (window.attachevent) {
doscroll ();
};
};
/*Doscroll menentukan apakah DOM IE6-8 telah dimuat.
*
*@param null
*@Execute Doscroll menentukan apakah DOM memuat
*@penelepon bindready ()
*/
fungsi doscroll () {
mencoba{
document.documentelement.doscroll ('kiri');
}
catch (error) {
kembalikan setTimeout (doscroll, 20);
};
execfn ();
};
/*Antrian Acara Eksekusi
*
*@param null
*@Execute Loop Execution Event Handler di Antrian
*@penelepon bindready ()
*/
fungsi execFn () {
if (! isready) {
isready = true;
untuk (var i = 0; i <eventqueue.length; i ++) {
EventQueue [i] .call (window);
};
EventQueue = [];
};
};
// file js 1
domready (function () {
...
});
// file js 2
domready (function () {
...
});
// Perhatikan bahwa jika dimuat secara tidak sinkron, jangan mengikat metode domready, jika tidak fungsi tidak akan dieksekusi.
// Karena sebelum unduhan JS yang memuat asinkron, domcontentloaded telah dipecat, dan addeventListener tidak dapat didengarkan saat mengeksekusi
Halaman Uji: Dua gambar besar dimuat. Onload membutuhkan gambar yang akan dimuat sebelum JS dapat dieksekusi. DOMContentLoaded hanya perlu menunggu sampai DOM dimuat untuk mengeksekusi JS. Anda dapat membuka Firebug untuk melihat proses pemuatan. Ingatlah untuk membersihkan cache browser sebelum setiap tes.