window.onload vs document.onload


709

Що більш широко підтримується: window.onloadчи document.onload?


2
Документи MDN пояснюють ці windowподії: onloadта DOMContentLoaded. Приклад використання :, window.addEventListener('DOMContentLoaded', callback). Станом на середину 2019 року сумісний з усіма основними браузерами. ----- developer.mozilla.org/en-US/docs/Web/API/Window/… ------ developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Крейг Хікс

Для мене навіть досі, у Firefox 75.0 сьогодні, window.onloadі document.onloadвони відрізняються один від одного! window.onloadздається, відбудеться згодом і трохи завантажений ніж document.onload! (Деякі речі працюють з вікном, яке не працює з документом! Це стосується і документа.Замкнути "завершити" також
Андрій,

Відповіді:


722

Коли вони стріляють?

window.onload

  • За замовчуванням він запускається, коли завантажується вся сторінка, включаючи її вміст (зображення, CSS, сценарії тощо).

У деяких веб-переглядачах вона тепер бере на себе роль document.onload та звільняється, коли DOM також готовий.

document.onload

  • Він називається, коли DOM буде готовий, що може бути перед завантаженням зображень та іншого зовнішнього вмісту.

Наскільки добре їх підтримують?

window.onloadяк видається, найбільш широко підтримується. Насправді деякі з найсучасніших браузерів у певному сенсі заміненіdocument.onload на window.onload.

Проблеми з підтримкою браузера, швидше за все, є причиною того, що багато людей починають використовувати бібліотеки, такі як jQuery, для обробки перевірки готовності документа, наприклад:

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

З метою історії. window.onloadvs body.onload:

Аналогічне запитання було задано на кодуванняфорумах деякий час назад щодо використання window.onloadover body.onload. Результатом здавалося, що ви повинні використовувати, window.onloadтому що добре відокремити структуру від дії.


25
На насправді це твердження , здається, направлено на вибір між window.onloadі <body onload="">який повністю відрізняється (і «окрема структура від дії» робить набагато більше сенсу в даному контексті). Не те, що відповідь неправильна, але в основі її є.
Thor84no

2
Ця цитата є граматично жахливою ... чи не повинні допомогти деякі (позначені) редагування?
Хельдар

@ Thor84no Я нарешті знайшов час поглянути ще раз на це. Я зробив декілька вдосконалень.
Джош Майн

@Hheldar Я вирішив перефразувати цитату, оскільки вона була досить грубою.
Джош Майн

@JoshMein Це означає, що document.onloadJS-еквівалент jQuery document.ready?
john cj

276

Загальна ідея полягає в тому, що window.onload запускається, коли вікно документа готове до представлення, а document.onload запускається, коли дерево DOM (побудоване з коду розмітки в документі) завершено .

В ідеалі, підписка на події дерева DOM , дозволяє керувати екранами через Javascript, не приносячи майже ніякого завантаження процесора . Навпаки, це window.onloadможе зайняти деякий час , коли пожежа ще потрібна , проаналізована та завантажена.

►Тест-сценарій:

Для того, щоб спостерігати різницю і як ваш браузер добірних реалізують вищезгадані обробник подій , просто вставте наступний код в вашому документі - <body>- тег.

<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>

►Результат:

Ось така поведінка, яка спостерігається для Chrome v20 (і, мабуть, більшості сучасних браузерів).

  • Жодної document.onloadподії.
  • onloadзапускається двічі, коли оголошується всередині <body>, один раз, коли оголошується всередині <head>(де подія діє тоді якdocument.onload ).
  • підрахунок та дія залежно від стану лічильника дозволяє наслідувати обидва події.
  • Альтернативно оголосити window.onloadобробник подій у межах HTML- <head>елемента.

►Прикладний проект:

Код, наведений вище, взято з бази даних коду ( і ) цього проекту .index.htmlkeyboarder.js


Щоб отримати список обробників подій об’єкта вікна , зверніться до документації MDN.


142

Додати слухача подій

<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

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


2 jQuery

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


Щасти.


14
"Подія DOMContentLoaded запускається, коли початковий документ HTML повністю завантажений та проаналізований, не чекаючи завантаження таблиць стилів, зображень та підкадрів." - developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded Тож ви, здається, неправі щодо того, що все завантажується на цю подію.
ПрофК

2
@ProfK, дякую за відгук. Ви можете спробувати window.addEventListener('load', function() {...}). Я також оновив свою відповідь.
Акаш

4
Що мені подобається у цій відповіді, це те, що вона дає звичайне старе рішення Javascript. Ви б могли подумати, що більшість людей вважають, що jQuery вбудований у всі браузери, враховуючи, наскільки часто він задається єдиною відповіддю.
Дейв Ленд

Подвійна проблема, коли чортове jquery завантажується занадто багато часу, і ви отримуєте $ не знайдено. Я вважаю, що рішення типу $ (window) .ready ніколи не слід довіряти роботі.
Шейне

1
Я спробував обидва у сьогоднішньому хромі. Це не чекання css та шрифтів.
movAX13h

78

Відповідно до аналізу документів HTML - Кінець ,

  1. Браузер аналізує джерело HTML та запускає відкладені сценарії.

  2. A DOMContentLoadedвідправляється в той documentмомент, коли всі HTML були проаналізовані та запущені. Подія бульбашки до window.

  3. Браузер завантажує ресурси (наприклад, зображення), які затримують подію завантаження.

  4. loadПодія відправляється на window.

Тому буде порядок виконання

  1. DOMContentLoadedслухачів подій windowу фазі захоплення
  2. DOMContentLoaded слухачів події document
  3. DOMContentLoadedслухачі подій windowу фазі міхура
  4. loadслухачів подій (включаючи onloadобробника подій) програмиwindow

loadСлухач подій бульбашки (включаючи onloadобробник подій) у documentніколи не повинен викликатися. loadВикликати можуть лише слухачі захоплення , але через завантаження підресурсу, як таблиця стилів, а не через завантаження самого документа.

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


Я запустив ваш фрагмент і document - load - captureсправді це трапляється, що суперечить тому, що я очікував у пошуку, чому завантаження документів не відбувається для мене. Як не дивно, це непослідовно. Іноді вона з’являється, іноді ні, іноді вона з’являється двічі - але ніколи не document - load - bubbleбуває. Я б запропонував не використовувати document load.
помилка

@erroric Добре. Я не вважав, що loadподія надсилається на зовнішні ресурси. Ця подія не є бульбашкою, тому її зазвичай не виявляють у документі, але це має бути у фазі захоплення. Ці записи стосуються навантаження елементів <style>та <script>елементів. Я думаю, що Edge підходить для їх показу, а Firefox та Chrome помиляються.
Оріол

Дякую Оріолу, useCaptureваріант навчив мене чомусь новому.
Пол Уотсон

Дякуємо, що узагальнили синтаксичний аналіз та потік візуалізації від w3. Мені просто цікаво, що після кроку 4 після запуску події "завантаження", що ще може статися? Я помітив у своєму браузері, що іноді все-таки з’являються деякі об’єкти, які витягуються після запуску події завантаження, хоча я взагалі не торкався і не спілкувався зі сторінкою. Чи знаєте ви, як називаються ті об’єкти? 'Неблокуючі об'єкти візуалізації?
weefwefwqg3

12

У Chrome, window.onload відрізняється від <body onload="">, тоді як вони однакові як у Firefox (версія 35.0), так і в IE (версія 11).

Ви можете дослідити це за наступним фрагментом:

<!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>

І на консолі Chrome ви побачите як "вікно завантажене" (яке по-перше), так і "завантаження тіла". Однак у Firefox та IE ви побачите просто "завантаження тіла". Якщо ви запустите " window.onload.toString()" в консолях IE & FF, ви побачите:

"функція завантаження (подія) {bodyOnloadHandler ()}"

що означає, що призначення "window.onload = function (e) ..." перезаписане.


6

window.onloadі onunloadце ярлики до document.body.onloadтаdocument.body.onunload

document.onloadа onloadобробник усіх тегів HTML, схоже, зарезервований, проте ніколи не запускається

' onload' в документі -> true


5

window.onload, однак, вони часто те саме. Аналогічно body.onload стає window.onload в IE.


1

Window.onload - це стандарт, однак веб-браузер в PS3 (заснований на Netfront) не підтримує об’єкт вікна, тому ви не можете його використовувати там.


0

Коротко

  • windows.onloadце не підтримуються IE 6-8
  • document.onload не підтримується жодним сучасним браузером (подія ніколи не запускається)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.