Страница: DOMContentLoaded, load, beforeunload, unload
У жизненного цикла HTML-страницы есть три важных события:
- DOMContentLoaded – браузер полностью загрузил HTML, было построено DOM-дерево, но внешние ресурсы, такие как картинки
и стили, могут быть ещё не загружены.
- load – браузер загрузил HTML и внешние ресурсы (картинки, стили и т.д.).
- beforeunload/unload – пользователь покидает страницу.
Каждое из этих событий может быть полезно:
- Событие DOMContentLoaded – DOM готов, так что обработчик может искать DOM-узлы и инициализировать интерфейс.
- Событие load – внешние ресурсы были загружены, стили применены, размеры картинок известны и т.д.
- Событие beforeunload – пользователь покидает страницу. Мы можем проверить, сохранил ли он изменения и спросить, на самом ли деле он хочет уйти.
- unload – пользователь почти ушёл, но мы всё ещё можем запустить некоторые операции, например, отправить статистику.
Давайте рассмотрим эти события подробнее.
DOMContentLoaded
Событие DOMContentLoaded срабатывает на объекте document .
Мы должны использовать addEventListener , чтобы поймать его:
document.addEventListener("DOMContentLoaded", ready); // не "document.onDOMContentLoaded = . "
В этом примере обработчик DOMContentLoaded запустится, когда документ загрузится, так что он увидит все элементы, включая расположенный ниже .
Но он не дожидается, пока загрузится изображение. Поэтому alert покажет нулевой размер.
На первый взгляд событие DOMContentLoaded очень простое. DOM-дерево готово – получаем событие. Хотя тут есть несколько особенностей.
DOMContentLoaded и скрипты
Когда браузер обрабатывает HTML-документ и встречает тег , он должен выполнить его перед тем, как продолжить строить DOM. Это делается на случай, если скрипт захочет изменить DOM или даже дописать в него ( document.write ), так что DOMContentLoaded должен подождать.
Поэтому DOMContentLoaded определённо случится после таких скриптов:
В примере выше мы сначала увидим «Библиотека загружена…», а затем «DOM готов!» (все скрипты выполнены).
Скрипты, которые не блокируют DOMContentLoaded
Есть два исключения из этого правила:
- Скрипты с атрибутом async , который мы рассмотрим немного позже, не блокируют DOMContentLoaded.
- Скрипты, сгенерированные динамически при помощи document.createElement(‘script’) и затем добавленные на страницу, также не блокируют это событие.
DOMContentLoaded и стили
Внешние таблицы стилей не затрагивают DOM, поэтому DOMContentLoaded их не ждёт.
Но здесь есть подводный камень. Если после стилей у нас есть скрипт, то этот скрипт должен дождаться, пока загрузятся стили:
Причина в том, что скрипту может понадобиться получить координаты или другие свойства элементов, зависящих от стилей, как в примере выше. Естественно, он должен дождаться, пока стили загрузятся.
Так как DOMContentLoaded дожидается скриптов, то теперь он так же дожидается и стилей перед ними.
Встроенное в браузер автозаполнение
Firefox, Chrome и Opera автоматически заполняют поля при наступлении DOMContentLoaded .
Например, если на странице есть форма логина и пароля и браузер запомнил значения, то при наступлении DOMContentLoaded он попытается заполнить их (если получил разрешение от пользователя).
Так что, если DOMContentLoaded откладывается из-за долгой загрузки скриптов, в свою очередь – откладывается автозаполнение. Вы наверняка замечали, что на некоторых сайтах (если вы используете автозаполнение в браузере) поля логина и пароля не заполняются мгновенно, есть некоторая задержка до полной загрузки страницы. Это и есть ожидание события DOMContentLoaded .
window.onload
Событие load на объекте window наступает, когда загрузилась вся страница, включая стили, картинки и другие ресурсы. Это событие доступно через свойство onload .
В примере ниже правильно показаны размеры картинки, потому что window.onload дожидается всех изображений:

window.onunload
Когда посетитель покидает страницу, на объекте window генерируется событие unload . В этот момент стоит совершать простые действия, не требующие много времени, вроде закрытия связанных всплывающих окон.
Обычно здесь отсылают статистику.
Предположим, мы собрали данные о том, как используется страница: клики, прокрутка, просмотры областей страницы и так далее.
Естественно, событие unload – это тот момент, когда пользователь нас покидает и мы хотим сохранить эти данные.
Для этого существует специальный метод navigator.sendBeacon(url, data) , описанный в спецификации https://w3c.github.io/beacon/.
Он посылает данные в фоне. Переход к другой странице не задерживается: браузер покидает страницу, но всё равно выполняет sendBeacon .
Его можно использовать вот так:
let analyticsData = < /* объект с собранными данными */ >; window.addEventListener("unload", function() < navigator.sendBeacon("/analytics", JSON.stringify(analyticsData)); >);
- Отсылается POST-запрос.
- Мы можем послать не только строку, но так же формы и другие форматы, как описано в главе Fetch, но обычно это строковый объект.
- Размер данных ограничен 64 Кб.
К тому моменту, как sendBeacon завершится, браузер наверняка уже покинет страницу, так что возможности обработать ответ сервера не будет (для статистики он обычно пустой).
Для таких запросов с закрывающейся страницей есть специальный флаг keepalive в методе fetch для общих сетевых запросов. Вы можете найти больше информации в главе Fetch API.
Если мы хотим отменить переход на другую страницу, то здесь мы этого сделать не сможем. Но сможем в другом месте – в событии onbeforeunload .
window.onbeforeunload
Если посетитель собирается уйти со страницы или закрыть окно, обработчик beforeunload попросит дополнительное подтверждение.
Если мы отменим это событие, то браузер спросит посетителя, уверен ли он.
Вы можете попробовать это, запустив следующий код и затем перезагрузив страницу:
window.onbeforeunload = function() < return false; >;
По историческим причинам возврат непустой строки так же считается отменой события. Когда-то браузеры использовали её в качестве сообщения, но, как указывает современная спецификация, они не должны этого делать.
window.onbeforeunload = function() < return "Есть несохранённые изменения. Всё равно уходим?"; >;
Поведение было изменено, потому что некоторые веб-разработчики злоупотребляли этим обработчиком события, показывая вводящие в заблуждение и надоедливые сообщения. Так что, прямо сейчас старые браузеры всё ещё могут показывать строку как сообщение, но в остальных – нет возможности настроить показ сообщения пользователям.
readyState
Что произойдёт, если мы установим обработчик DOMContentLoaded после того, как документ загрузился?
Естественно, он никогда не запустится.
Есть случаи, когда мы не уверены, готов документ или нет. Мы бы хотели, чтобы наша функция исполнилась, когда DOM загрузился, будь то сейчас или позже.
Свойство document.readyState показывает нам текущее состояние загрузки.
Есть три возможных значения:
- «loading» – документ загружается.
- «interactive» – документ был полностью прочитан.
- «complete» – документ был полностью прочитан и все ресурсы (такие как изображения) были тоже загружены.
Так что мы можем проверить document.readyState и, либо установить обработчик, либо, если документ готов, выполнить код сразу же.
Например, вот так:
function work() < /*. */ >if (document.readyState == 'loading') < // ещё загружается, ждём события document.addEventListener('DOMContentLoaded', work); >else < // DOM готов! work(); >
Также есть событие readystatechange , которое генерируется при изменении состояния, так что мы можем вывести все эти состояния таким образом:
// текущее состояние console.log(document.readyState); // вывести изменения состояния document.addEventListener('readystatechange', () => console.log(document.readyState));
Событие readystatechange – альтернативный вариант отслеживания состояния загрузки документа, который появился очень давно. На сегодняшний день он используется редко.
Для полноты картины давайте посмотрим на весь поток событий:
Здесь документ с , и обработчиками, которые логируют события:
log('img onload');
Рабочий пример есть в песочнице.
- [1] начальный readyState:loading
- [2] readyState:interactive
- [2] DOMContentLoaded
- [3] iframe onload
- [4] img onload
- [4] readyState:complete
- [4] window onload
Цифры в квадратных скобках обозначают примерное время события. События, отмеченные одинаковой цифрой, произойдут примерно в одно и то же время (± несколько миллисекунд).
- document.readyState станет interactive прямо перед DOMContentLoaded . Эти две вещи, на самом деле, обозначают одно и то же.
- document.readyState станет complete , когда все ресурсы ( iframe и img ) загрузятся. Здесь мы видим, что это произойдёт примерно в одно время с img.onload ( img последний ресурс) и window.onload . Переключение на состояние complete означает то же самое, что и window.onload . Разница заключается в том, что window.onload всегда срабатывает после всех load других обработчиков.
Итого
События загрузки страницы:
- DOMContentLoaded генерируется на document , когда DOM готов. Мы можем применить JavaScript к элементам на данном этапе.
- Скрипты, вроде или блокируют DOMContentLoaded, браузер ждёт, пока они выполнятся.
- Изображения и другие ресурсы тоже всё ещё могут продолжать загружаться.
- loading – документ грузится.
- interactive – документ прочитан, происходит примерно в то же время, что и DOMContentLoaded , но до него.
- complete – документ и ресурсы загружены, происходит примерно в то же время, что и window.onload , но до него.
Как осуществить перенаправление на другую веб-страницу с помощью JavaScript?
В этой статье мы рассмотрим различные способы JS redirect . Изучим запасные варианты перенаправления на тот случай, когда JavaScript отключен. А также влияние использования JavaScript для перенаправлений на SEO .
Перенаправление с помощью JavaScript
В идеале перенаправление должно осуществляться на стороне сервера с помощью корректного заголовка перенаправления HTTP , отправленного клиенту. Но если нужно перенаправить пользователя с помощью JavaScript , используйте для этого один из методов, приведенных ниже:
// перенаправление на новую страницу window.location.href = 'http://www.example.com/'; // то же, что и window.location.href = . window.location = 'http://www.example.com/'; window.location.assign('http://www.example.com/'); // перенаправление на другую страницу // с заменой первоначального документа в истории браузера на новый window.location.replace('http://www.example.com/');В большинстве случаев функция replace() является лучшим способом. Так как она не создаст циклического перенаправления в том случае, если пользователь нажмёт в своем браузере кнопку » Назад «.
Некоторые браузеры и большинство поисковых роботов не исполняют код JavaScript по разным причинам, поэтому нужен запасной вариант JS redirect page .
Запасной вариант на случай если JavaScript отключен :
Лучше всего использовать заголовки HTTP на стороне сервера, чтобы осуществлять перенаправление с соответствующим кодом. Но поскольку мы говорим исключительно о JavaScript-перенаправлениях , то можно использовать метатэг refresh (в секции ), чтобы приказать браузеру перезагрузить текущую страницу через указанное время. Рассмотрим следующий пример:
Ноль, указанный в атрибуте content , заставляет браузер осуществить перенаправление немедленно. Изменение этого параметра на положительное число прикажет браузеру сделать паузу перед обновлением страницы ( значение в секундах ).
Также можно реализовать запасной вариант. Например, ссылку, для устаревших браузеров, в которых тэг refresh не работает:
Чтобы убедиться, что код выполняется только, когда JavaScript отключен, можно обернуть метатэг в тэги noscript :
- Если страница выполняет перенаправление слишком быстро ( то есть меньше, чем за 2-3 секунды ), она может изменять поведение кнопки « Назад » в браузере. При этом каждый раз, когда вы будете перемещаться назад на исходную страницу, перенаправление осуществляется мгновенно. Это плохо в плане юзабилити, потому что может » запереть » пользователя на странице, на которую он был перенаправлен.
- Это может быть расценено как признак дорвейной страницы.
- Ошибка или плохо спланированные JS location redirect могут создать бесконечную последовательность перенаправлений, перебрасывая пользователя туда-сюда между несколькими страницами.
Влияние JavaScript-перенаправлений на SEO :
Почему JavaScript- перенаправление может отрицательно сказаться на позиции сайта в поисковых системах :
Большинство поисковых роботов не могут JavaScript-код , что может отрицательно повлиять на рейтинг страниц в выдаче. Использование тэга meta refresh не решит эту проблему для всех поисковых роботов.
HTML-страница , содержащая метатег refresh , возвращает код ответа HTTP 200 OK , что отличается от кодов ответа перенаправления — 301 , 302 и т.п. Как код ответа HTTP 200 OK с тэгом refresh интерпретируется браузером/ботом/роботом, зависит только от его задач и программного кода.
Альтернативы JavaScript-перенаправлению, не влияющие на SEO :
Лучшим способом исправить эту проблему является:
- Добавление тэга link rel=canonical в секцию веб-страницы, чтобы сообщить поисковым системам о дублировании страницы, например, . Этот вариант проще реализовать, так как он не подразумевает каких-либо изменений на стороне сервера. Но не все поисковые системы и роботы могут принимать во внимание этот тэг.
- Возвращение любого из следующих заголовков HTTP со стороны веб-сервера ( или серверного скрипта ):
- Заголовок перенаправления HTTP с наиболее верным кодом ответа перенаправления, например, 301, 302, и т.п.;
- Заголовок « 404 не найдено » для веб-страниц, от которых вы хотите окончательно избавиться.
Несмотря на то, что ответ 404 считается плохим с точки зрения SEO , он может иметь смысл в некоторых ситуациях. Чтобы определиться, какое действие для JS redirect to another page подходит для вас, задайте себе следующие вопросы:
- Существуют ли важные ссылки на страницу из внешних источников?
- Получает ли страница существенное количество трафика?
- Является ли этот URL-адрес популярным, на который пытаются попасть пользователи?
Если ответ на любой из этих вопросов да, то можно подумать об использовании перенаправления 3xx вместо ответа 404 . Иначе может выскочить 404 .
Причины этого следующие :
- мы сэкономим трафик запросов к серверу, исключив запросы поисковых систем, пытающихся добраться до удалённых или не нужных страниц;
- мы сможем корректно сообщить пользователю об ошибке, предоставив ему варианты поиска или другие связанные ссылки, что может улучшить пользовательский опыт.
Быстрое перенаправление после загрузки страницы
Разместив код перенаправления в разделе , можно выполнить немедленное перенаправление. Например:
window.location.href = "http://www.example.com";
В качестве альтернативы можно использовать событие onload тэга body :
Но всё, что предшествует тэгу body , будет выполнено браузером перед редиректом.
Перенаправление при загрузке страницы
Допустим, что перед выполнением JS redirect вы хотите убедиться, что страница закончила загрузку и выполнились определённые скрипты. В зависимости от того, когда нужно осуществить перенаправление, можно использовать следующие три события:
- Событие window.onload : возникает, когда объектная модель документа загружена, и весь контент загружен ( то есть всё загружено ).
- Событие document.onload : возникает, когда готова объектная модель документа ( строится из кода разметки ). То есть перед тем, как загружаются изображения или другой внешний контент.
- Событие document.onreadystatechange : возникает, когда:
- документ всё ещё загружается;
- документ загружен, но внешние ресурсы ( изображения, стили, фреймы и т.п .) ещё нет;
- документ и все внешние ресурсы загружены ( то же самое, что и событие window.onload ).
// Пример №1 window.addEventListener('load', function(event) < // все ресурсы загружены window.location = 'http://www.example.com/'; >); // Пример №2 document.onreadystatechange = function () < switch(document.readyState) < case 'loading': // документ всё ещё загружается break; case 'interactive': // документ загружен; теперь возможно обращение к элементам DOM break; case 'complete': // страница полностью загружена (то есть все ресурсы загружены) break; >>Перенаправление по истечении некоторого времени
Чтобы отсрочить JS redirect page на несколько секунд, можно использовать JavaScript-функцию setTimeout следующим образом:
// перенаправление через 3 секунды (или 3000 мс) setTimeout(function() < window.location.href = "http://www.example.com"; >, 3000);
- Время в функции setTimeout определяется в миллисекундах ( то есть 1000 мс = 1 секунда ).
- Так как отображение веб-страницы браузером происходит последовательно сверху вниз, тэги script ( которые не отмечены атрибутами defer или async ) загружаются и выполняются до того, как отображается страница. Поэтому размещение кода в блоке должно привести к немедленному выполнению кода и JS location redirec t после указанного количества миллисекунд . Но можно разместить код в конце веб-страницы. Код будет выполнен, когда браузер достигнет этого места в веб-документе.
Если у вас есть дополнения или замечания, оставьте их в комментариях ниже!
Как сделать появление контента без перезагрузки страницы?
Приветствую. Есть навигационная панель слева(вертикальная), используется bootstrap. Как сделать, чтобы при нажатии на разделы меню слева, справа появлялся контент этих разделов без перезагрузки страницы? Есть ли какие-то инструменты или подобные примеры реализации?
Отслеживать
задан 1 апр 2017 в 10:18
Роман Фридман Роман Фридман
1 4 4 бронзовых знака
1 апр 2017 в 10:25
– user269127
18 окт 2017 в 16:391 ответ 1
Сортировка: Сброс на вариант по умолчанию
Ну если не надо контент подгружать, то можно просто за каждым пунктом меню , закрепить свой блок контента и отображать его по клику.
$('.menu li').on('click',function()< var targetBlock = $(this).data('content'); $('.'+targetBlock).show().siblings('.hide').hide(); >);.conteiner < width:100%; height:100%; >.menu , .content < padding:5px; display:block; float:left; width:20%; background:#e1dede; >.menu li < cursor:pointer; >.content , li:hover < background:white; >.content .hide
Отслеживать
ответ дан 1 апр 2017 в 10:56
1,668 10 10 серебряных знаков 15 15 бронзовых знаков- html
- jquery
- bootstrap
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.11.21.1314
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Как менять контент на html странице без перезагрузки страницы?
Добрый день, я новичок в этой теме.
У меня есть страничка index.html генерируется Python\Flask, если страничка меняется — чтобы увидеть изменения — нужно обновить страницу в браузере, оно и понятно.Хочу сделать так: браузер раз в 0.5 секунды запрашивает контент — если поменялся — меняет его на странице, без перезагрузки.
Задача учебная, данных мало, можно всю страницу целиком перезагрузить. Как это сделать?- Вопрос задан более трёх лет назад
- 462 просмотра
