Как проверить, готов ли DOM без фреймворка?
Вопрос такой, как миллионы других здесь и в Интернете - Как проверить, загружен ли DOM в Javascript? Но вот подвох:
- Без использования фреймворка, такого как jQuery и т. Д.;
- Не зная, был ли ваш скрипт загружен через статически
<script>
тег или через какой-либо другой Javascript намного позже, после того, как DOM уже загружен.
Можно ли сделать это более или менее надежно и с кросс-браузерной совместимостью?
Добавлено: Позвольте уточнить: я пишу отдельный файл.JS, который может быть включен в произвольные веб-страницы. Я хочу выполнить код ПОСЛЕ загрузки DOM. Но я не знаю, КАК мой сценарий будет включен. Это может быть путем размещения <script>
тег (в этом случае традиционный onload
или DOM-готовые решения будут работать); или он может быть загружен через AJAX или каким-либо другим способом, намного позже, после того, как DOM уже загружен (поэтому ранее упомянутые решения никогда не сработают).
7 ответов
document.readyState
свойство может быть использовано для проверки готовности документа:
if(document.readyState === "complete") {
//Already loaded!
}
else {
//Add onload or DOMContentLoaded event listeners here: for example,
window.addEventListener("onload", function () {/* your code here */}, false);
//or
//document.addEventListener("DOMContentLoaded", function () {/* code */}, false);
}
Если полагаться на document.readyState
все в порядке, быстрое и грязное решение с опросом:
(function() {
var state = document.readyState;
if(state === 'interactive' || state === 'complete') {
// do stuff
}
else setTimeout(arguments.callee, 100);
})();
Браузеры Firefox, Opera и Webkit имеют событие уровня документа DOMContentLoaded
что вы можете слушать с document.addEventListener("DOMContentLoaded", fn, false)
,
Это сложнее в IE. Что делает jQuery в IE - это смотреть onreadystatechange
на объекте документа для определенного состояния готовности с резервной копией события document.onload. document.onload запускается позже, чем DOM готов (только после завершения загрузки всех изображений), поэтому он используется только как обратная остановка в случае, если более ранние события не работают по какой-либо причине.
Если вы потратите некоторое время на поиск в Google, вы найдете код для этого. Я полагаю, что наиболее проверенный код для этого находится в больших фреймворках, таких как jQuery и YUI, поэтому, даже если я не использую этот фреймворк, я ищу в их исходном коде методы.
Вот основная часть исходного кода jQuery 1.6.2 для document.ready()
:
bindReady: function() {
if ( readyList ) {
return;
}
readyList = jQuery._Deferred();
// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
return setTimeout( jQuery.ready, 1 );
}
// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
window.addEventListener( "load", jQuery.ready, false );
// If IE event model is used
} else if ( document.attachEvent ) {
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent( "onreadystatechange", DOMContentLoaded );
// A fallback to window.onload, that will always work
window.attachEvent( "onload", jQuery.ready );
// If IE and not a frame
// continually check to see if the document is ready
var toplevel = false;
try {
toplevel = window.frameElement == null;
} catch(e) {}
if ( document.documentElement.doScroll && toplevel ) {
doScrollCheck();
}
}
},
Это работает для всех браузеров и является кратким и кратким:
var execute = function () {
alert("executing code");
};
if ( !!(window.addEventListener) )
window.addEventListener("DOMContentLoaded", execute)
else // MSIE
window.attachEvent("onload", execute)
DOMContentLoaded
событие вызывается, когда исходный HTML-документ полностью загружен и проанализирован, не дожидаясь окончания загрузки таблиц стилей, изображений и подкадров. Хорошо, что Chrome, Firefox, IE9, Opera и Safari поддерживают его в равной степени.
document.addEventListener("DOMContentLoaded", function(event)
{
console.log("DOM fully loaded and parsed");
}
ПРИМЕЧАНИЕ. Internet Explorer 8 поддерживает событие readystatechange, которое можно использовать для определения готовности DOM.
Мы можем просто использоватьDOMContentLoaded
это чистый подход JavaScript.
Вот один из способов - запустить скрипт внизу страницы. Кроме того, используя window.onload, вы можете дождаться загрузки всех изображений / скриптов. Или вы можете просто разместить код внизу, не дожидаясь загрузки изображений.
<html>
<head>
</head>
<body>
</body>
<script language="text/javascript">
window.onload = (function (oldOnLoad) {
return function () {
if (oldOnLoad) {
olOnLoad(); //fire old Onload event that was attached if any.
}
// your code to run after images/scripts are loaded
}
})(window.onload);
// your code to run after DOM is loaded
</script>
</html>
Отредактировано: для комментария Вилкса
Многие привязки при загрузке - вот пример http://jsfiddle.net/uTF2N/3/