- $(document).ready vs $(window).load vs window.onload
- Страница: DOMContentLoaded, load, beforeunload, unload
- DOMContentLoaded
- DOMContentLoaded и скрипты
- DOMContentLoaded и стили
- Встроенное в браузер автозаполнение
- window.onload
- window.onunload
- window.onbeforeunload
- readyState
- window load inside a document ready?
- 4 Answers 4
- Difference between $(window).load() and $(document).ready() functions
- 11 Answers 11
- Почему $(window).load выполняется раньше, чем $(document).ready?
- 5 ответов 5
- $(window).load
- $(document).ready
- $(window).load или $(document).ready ?
$(document).ready vs $(window).load vs window.onload
Данный материал является вольным переводом статьи:
RITURAJ RATAN $(document).ready vs $(window).load vs window.onload
Длительное время мы использовали ‘$(document).ready’ работая с jQuery. Написанный таким образом код начнёт выполняться сразу после того, как будет готов DOM, за исключением картинок. Указанный код будет выполняться непосредственно после готовности DOM, не дожидаясь полной загрузки изображений. Вызов $(document).ready несколько раз приведет к последовательному исполнению вызовов друг за другом. Существуют ещё несколько вариантов записи.
Если мы говорим о $(window).load то код, написанный внутри такой конструкции, начнёт работу когда будет готов весь DOM включая изображения. Такой вызов подойдёт если мы хотим работать с изображениями (расчёт размеров изображения). Данный вызов, как и предыдущий является jQuery событием. Если на нашей странице есть изображения, то сначала мы дождёмся загрузки их всех, а потом будет вызван код.
И ещё кое-что, не путайте событие window load с jQuery методом ajax load.
Событие onload является стандартным событием в DOM, а описанные выше решения работают только при наличии библиотеки jQuery. Данный вариант имеет такую же функциональность как $(window).load , но является встроенным JavaScript событием. Событие onload происходит, когда объект был загружен. Мы можем сделать такой вызов непосредственно из тега. Например, разместив его в теге изображения и как только оно будет загружено произойдёт вызов события.
Такой вызов возможен как в HTML так и в JS.
Alert “вызов после загрузки body” будет вызван сразу после того как загрузится body
Если рассмотреть пример работы onload после загрузки изображения, то выглядеть все будет как показано ниже
Страница: DOMContentLoaded, load, beforeunload, unload
У жизненного цикла HTML-страницы есть три важных события:
- DOMContentLoaded – браузер полностью загрузил HTML, было построено DOM-дерево, но внешние ресурсы, такие как картинки и стили, могут быть ещё не загружены.
- load – браузер загрузил HTML и внешние ресурсы (картинки, стили и т.д.).
- beforeunload/unload – пользователь покидает страницу.
Каждое из этих событий может быть полезно:
- Событие DOMContentLoaded – DOM готов, так что обработчик может искать DOM-узлы и инициализировать интерфейс.
- Событие load – внешние ресурсы были загружены, стили применены, размеры картинок известны и т.д.
- Событие beforeunload – пользователь покидает страницу. Мы можем проверить, сохранил ли он изменения и спросить, на самом ли деле он хочет уйти.
- unload – пользователь почти ушёл, но мы всё ещё можем запустить некоторые операции, например, отправить статистику.
Давайте рассмотрим эти события подробнее.
DOMContentLoaded
Событие DOMContentLoaded срабатывает на объекте document .
Мы должны использовать addEventListener , чтобы поймать его:
В этом примере обработчик DOMContentLoaded запустится, когда документ загрузится, так что он увидит все элементы, включая расположенный ниже .
Но он не дожидается, пока загрузится изображение. Поэтому alert покажет нулевой размер.
На первый взгляд событие DOMContentLoaded очень простое. DOM-дерево готово – получаем событие. Хотя тут есть несколько особенностей.
DOMContentLoaded и скрипты
Когда браузер обрабатывает HTML-документ и встречает тег
В примере выше мы сначала увидим «Библиотека загружена…», а затем «DOM готов!» (все скрипты выполнены).
Есть два исключения из этого правила:
- Скрипты с атрибутом async , который мы рассмотрим немного позже, не блокируют DOMContentLoaded.
- Скрипты, сгенерированные динамически при помощи document.createElement(‘script’) и затем добавленные на страницу, также не блокируют это событие.
DOMContentLoaded и стили
Внешние таблицы стилей не затрагивают DOM, поэтому DOMContentLoaded их не ждёт.
Но здесь есть подводный камень. Если после стилей у нас есть скрипт, то этот скрипт должен дождаться, пока загрузятся стили:
Причина в том, что скрипту может понадобиться получить координаты или другие свойства элементов, зависящих от стилей, как в примере выше. Естественно, он должен дождаться, пока стили загрузятся.
Так как DOMContentLoaded дожидается скриптов, то теперь он так же дожидается и стилей перед ними.
Встроенное в браузер автозаполнение
Firefox, Chrome и Opera автоматически заполняют поля при наступлении DOMContentLoaded .
Например, если на странице есть форма логина и пароля и браузер запомнил значения, то при наступлении DOMContentLoaded он попытается заполнить их (если получил разрешение от пользователя).
Так что, если DOMContentLoaded откладывается из-за долгой загрузки скриптов, в свою очередь – откладывается автозаполнение. Вы наверняка замечали, что на некоторых сайтах (если вы используете автозаполнение в браузере) поля логина и пароля не заполняются мгновенно, есть некоторая задержка до полной загрузки страницы. Это и есть ожидание события DOMContentLoaded .
window.onload
Событие load на объекте window наступает, когда загрузилась вся страница, включая стили, картинки и другие ресурсы.
В примере ниже правильно показаны размеры картинки, потому что window.onload дожидается всех изображений:
window.onunload
Когда посетитель покидает страницу, на объекте window генерируется событие unload . В этот момент стоит совершать простые действия, не требующие много времени, вроде закрытия связанных всплывающих окон.
Обычно здесь отсылают статистику.
Предположим, мы собрали данные о том, как используется страница: клики, прокрутка, просмотры областей страницы и так далее.
Естественно, событие unload – это тот момент, когда пользователь нас покидает и мы хотим сохранить эти данные.
Для этого существует специальный метод navigator.sendBeacon(url, data) , описанный в спецификации https://w3c.github.io/beacon/.
Он посылает данные в фоне. Переход к другой странице не задерживается: браузер покидает страницу, но всё равно выполняет sendBeacon .
Его можно использовать вот так:
- Отсылается POST-запрос.
- Мы можем послать не только строку, но так же формы и другие форматы, как описано в главе Fetch, но обычно это строковый объект.
- Размер данных ограничен 64 Кб.
К тому моменту, как sendBeacon завершится, браузер наверняка уже покинет страницу, так что возможности обработать ответ сервера не будет (для статистики он обычно пустой).
Для таких запросов с закрывающейся страницей есть специальный флаг keepalive в методе fetch для общих сетевых запросов. Вы можете найти больше информации в главе Fetch API.
Если мы хотим отменить переход на другую страницу, то здесь мы этого сделать не сможем. Но сможем в другом месте – в событии onbeforeunload .
window.onbeforeunload
Если посетитель собирается уйти со страницы или закрыть окно, обработчик beforeunload попросит дополнительное подтверждение.
Если мы отменим это событие, то браузер спросит посетителя, уверен ли он.
Вы можете попробовать это, запустив следующий код и затем перезагрузив страницу:
По историческим причинам возврат непустой строки так же считается отменой события. Когда-то браузеры использовали её в качестве сообщения, но, как указывает современная спецификация, они не должны этого делать.
Поведение было изменено, потому что некоторые веб-разработчики злоупотребляли этим обработчиком события, показывая вводящие в заблуждение и надоедливые сообщения. Так что, прямо сейчас старые браузеры всё ещё могут показывать строку как сообщение, но в остальных – нет возможности настроить показ сообщения пользователям.
readyState
Что произойдёт, если мы установим обработчик DOMContentLoaded после того, как документ загрузился?
Естественно, он никогда не запустится.
Есть случаи, когда мы не уверены, готов документ или нет. Мы бы хотели, чтобы наша функция исполнилась, когда DOM загрузился, будь то сейчас или позже.
Свойство document.readyState показывает нам текущее состояние загрузки.
Есть три возможных значения:
- «loading» – документ загружается.
- «interactive» – документ был полностью прочитан.
- «complete» – документ был полностью прочитан и все ресурсы (такие как изображения) были тоже загружены.
Так что мы можем проверить document.readyState и, либо установить обработчик, либо, если документ готов, выполнить код сразу же.
Например, вот так:
Также есть событие readystatechange , которое генерируется при изменении состояния, так что мы можем вывести все эти состояния таким образом:
Событие readystatechange – альтернативный вариант отслеживания состояния загрузки документа, который появился очень давно. На сегодняшний день он используется редко.
Для полноты картины давайте посмотрим на весь поток событий:
Здесь документ с , и обработчиками, которые логируют события:
Рабочий пример есть в песочнице.
- [1] начальный readyState:loading
- [2] readyState:interactive
- [2] DOMContentLoaded
- [3] iframe onload
- [4] img onload
- [4] readyState:complete
- [4] window onload
Цифры в квадратных скобках обозначают примерное время события. События, отмеченные одинаковой цифрой, произойдут примерно в одно и то же время (± несколько миллисекунд).
window load inside a document ready?
Sorry if this has been answered before but all searches talk about the differences, not about using the two together, if possible.
Simply, can $(window).load.(function() <>) be used INSIDE of $(document).ready.(function() <>) ?
I have some things that should be done after the DOM is loaded but then I want to reveal certain elements only after the images have finished loading. The only thing that works in Explorer 8, is putting the $(window).load functions inside of the $(document).ready with everything else.
Is this an acceptable practice?
I just want to use the most acceptable method to reveal a DIV that contains small images, like a toolbar, after it’s fully constructed. ( visibility hidden versus display none , for example). The HTML for this DIV is written by the code inside the $(document).ready and then appended to the body using $(‘body’).append() before using the $(window).load .
I’m having lots of problems with Explorer 8.
4 Answers 4
This works fine and is an acceptable practice. After all, as you describe, there may be cases where the logic in the $(window).load() handler depends on work taking place after the DOM is ready. If the window is in fact already loaded by the time you set up $(window).load() , the handler will just fire immediately.
EDIT:
NOTE: This answer is only applicable to jQuery v2 and below.
The handler passed to .ready() is guaranteed to be executed after the DOM is ready, so this is usually the best place to attach all other event handlers and run other jQuery code.
The load event is sent to an element when it and all sub-elements have been completely loaded. This event can be sent to any element associated with a URL: images, scripts, frames, iframes, and the window object.
Based on the jQuery documentation above, I’ve seen nothing that would indicate any issues with the following:
Placing a .load inside of a ready simply guarantees that the DOM is ready whenever the load is fired.
One may wish to place all jQuery code within a single DOM ready handler, and yet still may have a sub-set of jQuery code that requires all images be loaded first. This arrangement guarantees that all code be triggered once on DOM ready and the rest will be triggered subsequently whenever the page assets have finished loading.
This may ultimately be more of an issue of personal preference, however the OP was clearly asking if this arrangement would cause problems. This has not proven to be true.
Difference between $(window).load() and $(document).ready() functions
What is the difference between $(window).load(function() <>) and $(document).ready(function() <>) in jQuery?
11 Answers 11
- document.ready is a jQuery event, it runs when the DOM is ready, e.g. all elements are there to be found/used, but not necessarily all content.
- window.onload fires later (or at the same time in the worst/failing cases) when images and such are loaded, so if you’re using image dimensions for example, you often want to use this instead.
The $(window).load() is NOT available in jQuery 3.0
To get around it, you can use it as an «Event Handler Attachment»
The difference are:
$(window).load() event is fired after whole content is loaded.
window.load will be triggered after all the iframe content is loaded
$(document).ready happens when all the elements are present in the DOM, but not necessarily all content.
window.onload or $(window).load() happens after all the content resources (images, etc) have been loaded.
From jquery prospective — it’s just adding load / onload event to window and document. Check this out:
document.ready (jQuery) document.ready will execute right after the HTML document is loaded property, and the DOM is ready.
DOM: The Document Object Model (DOM) is a cross-platform and language-independent convention for representing and interacting with objects in HTML, XHTML and XML documents.
Почему $(window).load выполняется раньше, чем $(document).ready?
По идеи такого не должно быть, но судя по console.log() при повторных обращений к странице время от времени $(window).load выполняется раньше, чем завершится выполнение $(document).ready . Что это? Из-за кеширования страницы?
UPD: не помогает, поэтому дело не в кеше
UPD2: при перезагрузки страницы всегда все начинает корректно отрабатывать
5 ответов 5
Событие DOMContentLoaded , которое «вызывает» метод ready() у document происходит всегда раньше исходя из документации: https://developer.mozilla.org/ru/docs/Web/API/Document/readyState
Поэтому нужен ваш пример.
$(window).load
Событие load происходит, когда сам элемент и все его дочерние элементы полностью загружены. Это событие может происходить на элементах, которые обладают полями URL (объект window, картинки, скрипты, фреймы).
Замечание 1: в некоторых случаях, если картинка содержится в кеше браузера, событие load может не произойти. Для такого случая можно воспользоваться специальным событием event.special.load , которое определено в небольшом плагине.
Замечание 2: если вам не требуется готовность мультимедийных файлов, лучше воспользоваться методом .ready() , который устанавливает обработчик готовности структуры документа, что происходит раньше начала загрузки файлов мультимедиа.
Тут все предельно ясно, если пишем $(window).load то код, написанный внутри этой конструкции, начнёт работу когда будет готов весь DOM включая изображения. Такой вызов логичнее производить в случае, когда необходимо работать с изображениями (расчёт размеров изображения или еще что-то).
$(document).ready
$(document).ready код внутри блока начнёт выполняться сразу после того, когда будет готов DOM, за исключением картинок. Указанный код будет выполняться непосредственно после готовности DOM, не дожидаясь полной загрузки изображений. Вызов $(document).ready несколько раз приведет к последовательному исполнению вызовов друг за другом, в последовательности сверху вниз.
$(window).load или $(document).ready ?
Хотя, для воспроизведения такой ситуации потребуется немало усилий, все равно остаются нюансы. Иногда, такое возникает, когда внутри события ready срабатывает подписка на load к примеру, или наоборот, что приводит к странному поведению.
Если опираться на некоторые другие ответы, такие как:
то приходишь к выводу, что событие $(window).load всегда должно произойти после $(document).ready . Но, факт присутствия такого поведения имеется.
Теперь подумаем про кеширование страницы. Да, действительно, после того, как изображения будут закэшированы весь написанный вами код, скорее всего, начнет выполняться последовательно, сверху вниз. Таким образом получатся ситуации, когда $(window).load и $(document).ready оба этих блока будут ждать только загрузку DOM , а если еще и подписка на событие внутри события будет, то получится коллизия, и стоящий $(window).load перед $(document).ready выполнится раньше. В любом случае, коллизия происходит не просто так и нужно заняться исправлением кода и его рефакторингом.