window.onload против document.onload

712

Что более широко поддерживается: 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! (Некоторые вещи работают с окном, которое не работает с документом! Это также относится и к document.onreadstatechange 'complete'!)
Эндрю

Ответы:

723

Когда они стреляют?

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.onloadпротив body.onload:

Подобный вопрос был задан на форумах по кодированию некоторое время назад относительно использования window.onloadover body.onload. В результате, кажется, вы должны использовать, window.onloadпотому что это хорошо, чтобы отделить вашу структуру от действия.

Джош Майн
источник
25
На самом деле это утверждение, по-видимому, направлено на выбор между window.onloadи <body onload="">который совершенно отличается (и «отдельная структура от действия» имеет гораздо больше смысла в этом контексте). Не то, чтобы ответ был неправильным, но основа этого есть.
Thor84no
2
Эта цитата грамматически ужасна ... не должны ли некоторые (помеченные) редактировать?
Хельдар
@ Thor84no Я наконец-то нашел время посмотреть на это еще раз. Я сделал несколько улучшений.
Джош Майн
@Хелдар Я решил перефразировать цитату, так как она была довольно грубой.
Джош Майн
@JoshMein Значит ли это, что document.onloadэто JS-эквивалент jQuery document.ready?
Джон
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>

►Result:

Вот результирующее поведение, наблюдаемое для Chrome v20 (и, вероятно, большинства современных браузеров).

  • Нет document.onloadсобытий
  • onloadсрабатывает дважды при объявлении внутри <body>, один раз при объявлении внутри <head>(когда событие действует какdocument.onload ).
  • подсчет и действие в зависимости от состояния счетчика позволяет имитировать оба поведения событий.
  • В качестве альтернативы объявите window.onloadобработчик события в пределах HTML- <head>элемента.

► Пример проекта:

Код выше взят из кодовой базы этого проекта ( index.htmlи keyboarder.js).


Список обработчиков событий объекта window приведен в документации MDN.

Лоренц Ло Зауэр
источник
143

Добавить прослушиватель событий

<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 Таким образом, вы, похоже, ошибаетесь во всем, что загружается на этом мероприятии.
ProfK
2
@ProfK, спасибо за ваш отзыв. Можешь попробовать window.addEventListener('load', function() {...})? Я также обновил свой ответ.
Акаш
4
Что мне нравится в этом ответе, так это то, что он дает простое решение на основе javascript. Можно подумать, что большинство людей считают, что jQuery встроен во все браузеры, учитывая, как часто он дается в качестве единственного ответа.
Дейв Лэнд
Двойная проблема, когда чертов jquery загружается слишком долго и вы получаете $ not found. Я придерживаюсь мнения, что решения типа $ (window) .ready НИКОГДА не следует доверять работе.
Шейн
1
Я пробовал оба в сегодняшнем Chrome. Это не ждет 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 после запуска события load что еще может произойти? Я заметил в своем браузере, что иногда все еще некоторые объекты выбираются после запуска события load, хотя я вообще не касался страницы и не взаимодействовал с ней. Вы знаете, как называются эти объекты? Неблокирующие объекты рендеринга?
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, вы увидите:

"функция onload (событие) {bodyOnloadHandler ()}"

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

VincentZHANG
источник
6

window.onloadи onunloadярлыки document.body.onloadиdocument.body.onunload

document.onloadи onloadобработчик на все теги HTML, кажется, зарезервированы, но никогда не запускаются

' onload' в документе -> правда

garaboncias
источник
5

Window.onload, однако, они часто одно и то же. Точно так же body.onload становится window.onload в IE.

AnthonyWJones
источник
1

Однако Window.onload является стандартом - веб-браузер в PS3 (на основе Netfront) не поддерживает объект окна, поэтому вы не можете использовать его там.

gotofritz
источник
0

Короче говоря

  • windows.onloadэто не поддерживается IE 6-8
  • document.onload не поддерживается ни одним современным браузером (событие никогда не запускается)

Камил Келчевски
источник