Как определить, был ли запущен DOMContentLoaded
Я пытаюсь помочь в разработке библиотеки, и для этого я пытаюсь работать с загрузкой страницы.
В процессе я хочу сделать библиотеку полностью совместимой с использованием defer и async.
То, что я хочу, это просто:
Как я могу узнать, что DOMContentLoaded был запущен во время выполнения файла?
Почему это так сложно?
В IE document.readyState показывает интерактивную версию перед DOMContentLoaded.
Я не буду использовать обнаружение браузера никоим образом, это противоречит политике меня и остальных участников.
Какая правильная альтернатива?
Редактировать:
Похоже, я не достаточно ясно. Мне не интересно знать, если событие загрузки уже произошло!!! Я уже знал, как решить эту проблему! Я хочу знать, как решить с DOMContentLoaded!!!
5 ответов
Чтобы увидеть, все ли ресурсы на странице были загружены:
if (document.readyState === "complete" || document.readyState === "loaded") {
// document is already ready to go
}
Это давно поддерживается в IE и webkit. Он был добавлен в Firefox в версии 3.6. Вот спецификация. "loaded"
для старых браузеров Safari.
Если вы хотите знать, когда страница была загружена и проанализирована, но все подресурсы еще не были загружены (что более похоже на DOMContentLoaded
), вы можете добавить "интерактивное" значение:
if (document.readyState === "complete"
|| document.readyState === "loaded"
|| document.readyState === "interactive") {
// document has at least been parsed
}
Кроме того, если вы действительно хотите знать, когда был запущен DOMContentLoaded, вам придется установить для этого обработчик события (до его запуска) и установить флаг при его запуске.
Эта документация MDN также очень хорошо знакома с пониманием состояний DOM.
document.readyState
изменяется при запуске этого события. Таким образом, вы можете проверить readyState
значение и таким образом сказать, было ли событие сработало или нет. Вот код для запуска start()
когда документ готов к этому:
if (/comp|inter|loaded/.test(document.readyState)){
// In case DOMContentLoaded was already fired, the document readyState will be one of "complete" or "interactive" or (nonstandard) "loaded".
// The regexp above looks for all three states. A more readable regexp would be /complete|interactive|loaded/
start();
}else{
// In case DOMContentLoaded was not yet fired, use it to run the "start" function when document is read for it.
document.addEventListener('DOMContentLoaded', start, false);
}
Как правильно запустить что-то на DOMContentLoaded (или как можно скорее)
Если вам нужно дождаться полной загрузки и анализа HTML-документа, чтобы что-то запустить, вам нужно дождаться DOMContentLoaded
, насчет этого сомнений нет. Но если вы не можете контролировать, когда ваш скрипт будет выполняться, возможно, чтоDOMContentLoaded
уже был активирован к тому времени, когда у вас появилась возможность прослушать событие.
Чтобы принять это во внимание, ваш код должен проверить, DOMContentLoaded
уже был запущен, и, если это так, немедленно приступайте к выполнению всего, что необходимо для ожидания DOMContentLoaded
:
function runWhenPageIsFullyParsed() {
// your logic goes here
}
if (document.readyState === "complete") {
// already fired, so run logic right away
runWhenPageIsFullyParsed();
} else {
// not fired yet, so let's listen for the event
window.addEventListener("DOMContentLoaded", runWhenPageIsFullyParsed);
}
Правильный порядок событий при загрузке страницы:
document.readyState
изменения кinteractive
window
сDOMContentLoaded
событие запускаетсяdocument.readyState
изменения кcomplete
window
сload
событие запускаетсяload
Вы можете проверить полный порядок событий во время загрузки страницы в этой скрипке.
Попробуйте это или посмотрите на эту ссылку
<script>
function addListener(obj, eventName, listener) { //function to add event
if (obj.addEventListener) {
obj.addEventListener(eventName, listener, false);
} else {
obj.attachEvent("on" + eventName, listener);
}
}
addListener(document, "DOMContentLoaded", finishedDCL); //add event DOMContentLoaded
function finishedDCL() {
alert("Now DOMContentLoaded is complete!");
}
</script>
Заметка
Если у тебя есть <script>
после <link rel="stylesheet" ...>
страница не будет разбираться - и DOMContentLoaded
не будет запускаться - пока не будет загружена таблица стилей
Если вы хотите точно знать, был ли запущен DOMContentLoaded, вы можете использовать логический флаг следующим образом:
var loaded=false;
document.addEventListener('DOMContentLoaded',function(){
loaded=true;
...
}
затем проверьте с помощью:
if(loaded) ...
Дело в том, что если какая-то другая библиотека (например, jQuery) уже использовала DOMContentLoaded, вы не сможете использовать ее снова. Это может быть плохой новостью, потому что вы в конечном итоге не сможете ее использовать. Вы скажете, почему бы просто не использовать $(document).ready()
потому что, НЕТ!, не все должны использовать jQuery, особенно если это другая библиотека.