window.onload vs document.onload

712

Mana yang lebih banyak didukung: window.onloadatau document.onload?

Chris Ballance
sumber
2
Dokumen MDN menjelaskan windowperistiwa ini : onloaddan DOMContentLoaded. Contoh penggunaan :, window.addEventListener('DOMContentLoaded', callback). Pada pertengahan 2019, kompatibel dengan semua browser utama. ----- developer.mozilla.org/en-US/docs/Web/API/Window/… ------ developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Craig Hicks
Bagi saya bahkan masih, di Firefox 75,0 hari, window.onloaddan document.onloadyang berbeda satu sama lain! window.onloadtampaknya terjadi setelah itu dan memiliki sedikit lebih banyak daripada document.onload! (! Beberapa hal bekerja dengan jendela yang tidak bekerja dengan dokumen Itu berlaku untuk document.onreadstatechange 'lengkap' juga!)
Andrew

Jawaban:

723

Kapan mereka menembak?

window.onload

  • Secara default, ini diaktifkan ketika seluruh halaman memuat, termasuk kontennya (gambar, CSS, skrip, dll.).

Di beberapa browser sekarang mengambil alih peran document.onloaddan menyala ketika DOM siap juga.

document.onload

  • Disebut ketika DOM siap yang dapat sebelum gambar dan konten eksternal lainnya dimuat.

Seberapa baik mereka didukung?

window.onloadtampaknya menjadi yang paling banyak didukung. Bahkan, beberapa browser yang paling modern memiliki dalam arti diganti document.onloaddengan window.onload.

Masalah dukungan peramban kemungkinan besar merupakan alasan mengapa banyak orang mulai menggunakan pustaka seperti jQuery untuk menangani pemeriksaan dokumen yang siap, seperti:

$(document).ready(function() { /* code here */ });
$(function() { /* code here */ });

Untuk tujuan sejarah. window.onloadvs body.onload:

Pertanyaan serupa ditanyakan pada codingforums beberapa waktu lalu mengenai penggunaan window.onloadlebih body.onload. Hasilnya tampaknya harus Anda gunakan window.onloadkarena itu baik untuk memisahkan struktur Anda dari tindakan.

Josh Mein
sumber
25
Sebenarnya pernyataan itu tampaknya diarahkan pada pilihan antara window.onloaddan <body onload="">yang benar-benar berbeda (dan "struktur terpisah dari tindakan" jauh lebih masuk akal dalam konteks ini). Bukannya jawabannya salah, tapi dasarnya.
Thor84no
2
Kutipan itu mengerikan secara tata bahasa ... bukankah seharusnya ada bantuan penyuntingan (bertanda)?
Kheldar
@ Thor84, akhirnya aku menemukan waktu untuk melihat, lihat lagi ini. Saya telah membuat beberapa perbaikan.
Josh Mein
@Kheldar Saya memutuskan untuk memparafrasekan kutipan karena agak kasar.
Josh Mein
@ JoshMein Apakah itu berarti document.onloadJS-setara dengan jQuery document.ready?
john cj
276

Gagasan umum adalah bahwa window.onload menyala ketika jendela dokumen siap untuk presentasi dan document.onload menyala ketika pohon DOM (dibangun dari kode markup dalam dokumen) selesai .

Idealnya, berlangganan acara DOM-tree , memungkinkan manipulasi layar-lebar melalui Javascript, hampir tanpa beban CPU . Sebaliknya, window.onloaddapat memakan waktu cukup lama untuk diaktifkan , ketika beberapa sumber daya eksternal belum diminta, diuraikan dan dimuat.

► Skenario pengujian:

Untuk mengamati perbedaan dan bagaimana browser pilihan Anda mengimplementasikan event handler yang disebutkan di atas , cukup masukkan kode berikut dalam <body>tag - - dokumen Anda .

<script language="javascript">
window.tdiff = []; fred = function(a,b){return a-b;};
window.document.onload = function(e){ 
    console.log("document.onload", e, Date.now() ,window.tdiff,  
    (window.tdiff[0] = Date.now()) && window.tdiff.reduce(fred) ); 
}
window.onload = function(e){ 
    console.log("window.onload", e, Date.now() ,window.tdiff, 
    (window.tdiff[1] = Date.now()) && window.tdiff.reduce(fred) ); 
}
</script>

►Hasil:

Berikut adalah perilaku yang dihasilkan, dapat diamati untuk Chrome v20 (dan mungkin sebagian besar browser saat ini).

  • Tidak ada document.onloadacara
  • onloadKebakaran dua kali ketika dinyatakan di dalam <body>, sekali ketika dinyatakan di dalam <head>(di mana acara tersebut bertindak sebagai document.onload).
  • berhitung dan bertindak tergantung pada keadaan penghitung memungkinkan untuk meniru kedua perilaku acara.
  • Atau deklarasikan window.onloadevent handler dalam batas-batas <head>elemen HTML .

► Proyek Contoh:

Kode di atas diambil dari basis kode proyek ini ( index.htmldan keyboarder.js).


Untuk daftar penangan kejadian objek jendela , silakan merujuk ke dokumentasi MDN.

Lorenz Lo Sauer
sumber
143

Tambahkan Pendengar Acara

<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function(event) {
      // - Code to execute when all DOM content is loaded. 
      // - including fonts, images, etc.
  });
</script>


Update March 2017

1 JavaScript Vanila

window.addEventListener('load', function() {
    console.log('All assets are loaded')
})


2 jQuery

$(window).on('load', function() {
    console.log('All assets are loaded')
})


Semoga berhasil.

Akash
sumber
14
"Acara DOMContentLoaded dipecat ketika dokumen HTML awal telah dimuat dan diurai sepenuhnya, tanpa menunggu stylesheet, gambar, dan subframe selesai dimuat." - developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded Jadi Anda tampaknya salah tentang semua yang dimuat di acara ini.
ProfK
2
@ProfK, terima kasih atas tanggapan Anda. Bisakah kamu mencoba window.addEventListener('load', function() {...}). Saya juga memperbarui jawaban saya.
Akash
4
Yang saya sukai dari jawaban ini adalah memberikan solusi javascript biasa-lama. Anda akan berpikir bahwa kebanyakan orang berpikir jQuery dibangun di semua browser, mengingat seberapa sering itu diberikan sebagai satu-satunya jawaban.
Dave Land
Masalah ganda ketika jquery sialan butuh waktu terlalu lama untuk memuat dan Anda mendapatkan $ tidak ditemukan. Saya berpendapat bahwa $ (jendela). Solusi tipe yang sudah pernah PERNAH dipercaya untuk bekerja.
Shayne
1
Saya sudah mencoba keduanya di chrome todays. Itu tidak menunggu css dan font.
movAX13h
78

Menurut Parsing dokumen HTML - Akhirnya ,

  1. Browser mem-parsing sumber HTML dan menjalankan skrip yang ditangguhkan.

  2. A DOMContentLoadeddikirimkan pada documentsaat semua HTML telah diuraikan dan telah berjalan. Gelembung acara ke window.

  3. Browser memuat sumber daya (seperti gambar) yang menunda acara memuat.

  4. Sebuah loadacara dikirim di window.

Oleh karena itu, urutan pelaksanaannya adalah

  1. DOMContentLoadedpendengar acara windowdalam fase penangkapan
  2. DOMContentLoaded pendengar acara document
  3. DOMContentLoadedpendengar acara windowdalam fase gelembung
  4. loadpendengar acara (termasuk onloadpengendali acara) dariwindow

loadPendengar acara gelembung (termasuk onloadpenangan acara) di documenttidak boleh dipanggil. Hanya loadpendengar yang ditangkap yang dapat dipanggil, tetapi karena memuat sub-sumber daya seperti lembar gaya, bukan karena beban dokumen itu sendiri.

window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - capture'); // 1st
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - capture'); // 2nd
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - bubble'); // 2nd
});
window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - bubble'); // 3rd
});

window.addEventListener('load', function() {
  console.log('window - load - capture'); // 4th
}, true);
document.addEventListener('load', function(e) {
  /* Filter out load events not related to the document */
  if(['style','script'].indexOf(e.target.tagName.toLowerCase()) < 0)
    console.log('document - load - capture'); // DOES NOT HAPPEN
}, true);
document.addEventListener('load', function() {
  console.log('document - load - bubble'); // DOES NOT HAPPEN
});
window.addEventListener('load', function() {
  console.log('window - load - bubble'); // 4th
});

window.onload = function() {
  console.log('window - onload'); // 4th
};
document.onload = function() {
  console.log('document - onload'); // DOES NOT HAPPEN
};

Oriol
sumber
Saya menjalankan cuplikan Anda dan document - load - capturememang terjadi, yang bertentangan dengan apa yang saya harapkan dalam pencarian saya mengapa pemuatan dokumen tidak terjadi pada saya. Anehnya, itu tidak konsisten. Terkadang muncul, terkadang tidak, kadang muncul dua kali - tetapi tidak pernah document - load - bubbleterjadi. Saya sarankan tidak menggunakan document load.
galat
@ poin bagus. Saya tidak menganggap bahwa suatu loadperistiwa dikirim pada sumber daya eksternal. Peristiwa itu tidak menggelembung sehingga biasanya tidak terdeteksi pada dokumen, tetapi harus dalam fase penangkapan. Entri-entri ini merujuk pada muatan elemen <style>dan <script>. Saya pikir Edge tepat untuk menunjukkannya, dan Firefox serta Chrome salah.
Oriol
Terima kasih Oriol, useCaptureopsi mengajari saya sesuatu yang baru.
Paul Watson
Terima kasih telah meringkas aliran parsing dan rendering dari w3. Saya hanya ingin tahu setelah langkah 4 setelah acara 'memuat' dipecat, apa lagi yang bisa terjadi? Saya perhatikan di browser saya bahwa kadang-kadang masih ada beberapa objek yang diambil setelah memuat acara dipecat meskipun saya belum menyentuh atau berinteraksi dengan halaman sama sekali. Apakah Anda tahu benda apa itu disebut? 'Objek rendering yang tidak menghalangi?
weefwefwqg3
12

Di Chrome, window.onload berbeda dari <body onload="">, sedangkan keduanya sama di Firefox (versi 35.0) dan IE (versi 11).

Anda dapat menjelajahinya dengan cuplikan berikut:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <!--import css here-->
        <!--import js scripts here-->

        <script language="javascript">

            function bodyOnloadHandler() {
                console.log("body onload");
            }

            window.onload = function(e) {
                console.log("window loaded");
            };
        </script>
    </head>

    <body onload="bodyOnloadHandler()">

        Page contents go here.

    </body>
</html>

Dan Anda akan melihat "jendela dimuat" (yang datang terlebih dahulu) dan "tubuh dimuat" di konsol Chrome. Namun, Anda hanya akan melihat "body onload" di Firefox dan IE. Jika Anda menjalankan " window.onload.toString()" di konsol IE & FF, Anda akan melihat:

"function onload (event) {bodyOnloadHandler ()}"

yang berarti bahwa tugas "window.onload = fungsi (e) ..." ditimpa.

VincentZHANG
sumber
6

window.onloaddan onunloadmerupakan jalan pintas ke document.body.onloaddandocument.body.onunload

document.onloaddan onloadpenangan pada semua tag html tampaknya dicadangkan namun tidak pernah dipicu

' onload' dalam dokumen -> benar

garaboncias
sumber
5

window.onload namun mereka seringkali merupakan hal yang sama. Demikian pula body.onload menjadi window.onload di IE.

AnthonyWJones
sumber
1

Window.onload adalah standar, namun - browser web di PS3 (berdasarkan Netfront) tidak mendukung objek jendela, jadi Anda tidak dapat menggunakannya di sana.

Gotofritz
sumber
0

Pendeknya

  • windows.onloadyang tidak didukung oleh IE 6-8
  • document.onload tidak didukung oleh peramban modern mana pun (acara tidak pernah dipecat)

Kamil Kiełczewski
sumber