Почему $(window).load выполняется раньше, чем $(document).ready?

389
12 мая 2017, 16:43

По идеи такого не должно быть, но судя по console.log() при повторных обращений к странице время от времени $(window).load выполняется раньше, чем завершится выполнение $(document).ready. Что это? Из-за кеширования страницы?

UPD: <meta http-equiv="Cache-Control" content="no-cache" /> не помогает, поэтому дело не в кеше

UPD2: при перезагрузки страницы всегда все начинает корректно отрабатывать

Answer 1

Событие DOMContentLoaded, которое "вызывает" метод ready() у document происходит всегда раньше исходя из документации: https://developer.mozilla.org/ru/docs/Web/API/Document/readyState

Поэтому нужен ваш пример.

$(window).load(function() { 
  console.log("window"); 
}); 
 
$(document).ready(function() { 
  console.log("document"); 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Answer 2

$(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 к примеру, или наоборот, что приводит к странному поведению.

Если опираться на некоторые другие ответы, такие как:

  • After all $(document).ready() have run, is there an event for that?
  • window.onload vs $(document).ready()
  • multiple $(document).ready and $(window).load in $(document).ready

то приходишь к выводу, что событие $(window).load всегда должно произойти после $(document).ready. Но, факт присутствия такого поведения имеется.

Теперь подумаем про кеширование страницы. Да, действительно, после того, как изображения будут закэшированы весь написанный вами код, скорее всего, начнет выполняться последовательно, сверху вниз. Таким образом получатся ситуации, когда $(window).load и $(document).ready оба этих блока будут ждать только загрузку DOM, а если еще и подписка на событие внутри события будет, то получится коллизия, и стоящий $(window).load перед $(document).ready выполнится раньше. В любом случае, коллизия происходит не просто так и нужно заняться исправлением кода и его рефакторингом.

Полезные ссылки для ознакомления:

  • $(document).ready vs $(window).load vs window.onload
  • Обработчик события load .load()
  • Обработчик готовности дерева DOM .ready()
  • .ready()
  • .load()
  • Справочник jQuery Загрузка документа
Answer 3

Внимательно посмотрел Network в DevTools и проблему решил убрав ajax-запрос, который создавал картинку и выполнялся 10 сек.

Вот что происходило: Ajax отправив запрос и не получив ответ по какой-то причине считал, что DOM-построен и пора вызвать событие load, а через 10 сек прилетал ответ от, казалось бы, уже мертвого запроса, поэтому ready довыполнялся позже load =)

Answer 4

$(document).ready - Срабатывает когда браузер загрузил html и построил DOM дерево, а $(window).load - срабатывает когда еще и загружены все ресурсы (картинки и прочее), то есть теоретически $(document).ready срабатывает раньше, но после перезагрузки страницы ресурсы (картинки) ку нас могут быть закешированы, в таком случае $(window).load может начать выполнятся примерно совместно с $(document).ready.

Answer 5

Скорее всего подписка на возникающее позже событие делается уже из другого обработчика события load. Других способов воспроизвести такую ситуацию мне неизвестно.

READ ALSO
Вопрос по jQuery

Вопрос по jQuery

Здравствуйте, такой вопросЯ только начал изучать jQuery и мне нужна помощь

270
Очередь предстоящих событий в jquery

Очередь предстоящих событий в jquery

У меня должна сначала выполниться библиотека magnificPopup:

279
Передача результата функции jquery на другу страницу

Передача результата функции jquery на другу страницу

Доброго времени суток, есть такой вопрос, на который не нашел ответа (или не понял)Написал калькулятор на одной странице, он должен отправлять...

316
.on(&#39;click&#39;,&#39;handler&#39; function(){})

.on('click','handler' function(){})

Здравствуйте!

320