Я знаю, что есть несколько способов получить уведомление, когда тело страницы загружено (до загрузки всех изображений и сторонних ресурсов, что вызывает событие window.onload), но для каждого браузера он разный.
Есть ли окончательный способ сделать это во всех браузерах?
На данный момент я знаю:
DOMContentLoaded: в Mozilla, Opera 9 и новейших WebKits. Это включает добавление слушателя к событию:
document.addEventListener ("DOMContentLoaded", [функция инициализации], ложь);
Отложенный сценарий: в IE вы можете создать тег SCRIPT с атрибутом @defer, который будет надежно загружаться только после закрытия тега BODY.
Опрос: В других браузерах вы можете продолжать опросы, но есть ли даже стандартная функция для опроса, или вам нужно делать разные вещи в каждом браузере?
Я бы хотел обойтись без использования document.write или внешних файлов.
Это можно сделать просто через jQuery:
$(document).ready(function() { ... })
но я пишу библиотеку JS и не могу рассчитывать на то, что jQuery всегда будет там.
Нет, хотя IE9 теперь также поддерживает DOMContentLoaded. Так что мы просто сидим и ждем, пока доля рынка браузеров IE9 не опустится ниже 1%.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Просто возьмите соответствующий фрагмент кода из jQuery, Джон Ресиг охватил большинство основ по этой проблеме уже в jQuery.
Это работает очень хорошо:
setTimeout(MyInitFunction, 0);
Нет, это не так. Это ненадежно по большому счету. Извини. : - /
Не существует кроссбраузерного метода для проверки готовности DOM - вот почему существуют такие библиотеки, как jQuery, чтобы абстрагироваться от неприятных мелких кусочков несовместимости.
Mozilla, Opera и современный WebKit поддерживают событие DOMContentLoaded. IE и Safari нуждаются в странных хитростях, таких как прокрутка окна или проверка таблиц стилей. Кровавые подробности содержатся в функции jQuery bindReady().
YUI использует для этого три теста: для Firefox и недавнего WebKit запускается событие DOMContentLoaded. Для более старого Safari document.readyState просматривается, пока он не станет «загруженным» или «завершенным». Для IE создается тег HTML <P> и вызывается метод «doScroll ()», который должен срабатывать, если DOM не готов. Источник для YAHOO.util.Event показывает код, специфичный для YUI. Найдите «doScroll» в Event.js.
Использование такой библиотеки, как jQuery, сэкономит вам бесчисленное количество часов несогласованности браузеров.
В этом случае с jQuery вы можете просто
$(document).ready ( function () {
//your code here
});
Если вам интересно, вы можете взглянуть на источник, чтобы увидеть, как это делается, но в наши дни я не думаю, что кто-то должен изобретать это колесо, когда автор библиотеки проделал за вас всю болезненную работу.
Я нашел эту страницу, на которой показано компактное автономное решение. Кажется, он работает в каждом браузере и объясняет, как:
http://www.kryogenix.org/days/2007/09/26/shortloaded
Похоже, это получено из этого кода: javascript.nwbox.com/ContentLoaded. Я пробовал этот исходный код во множестве браузеров, и у меня он отлично сработал.
Использование setTimeout может работать достаточно хорошо, хотя когда он выполняется, зависит от браузера. Если вы передадите ноль в качестве времени ожидания, браузер выполнит работу, когда все будет «улажено».
Хорошо то, что у вас может быть много из них, и вам не нужно беспокоиться о связывании событий onLoad.
setTimeout(myFunction, 0);
setTimeout(anotherFunction, 0);
setTimeout(function(){ doSomething ...}, 0);
и Т. Д.
Все они будут запущены, когда документ завершит загрузку, или, если вы настроите один после загрузки документа, они будут запускаться после завершения вашего скрипта.
Порядок их выполнения не определен и может меняться в зависимости от браузера. Так что, например, вы не можете рассчитывать на то, что myFunction будет работать раньше, чем anotherFunction.
Все дело в том, чтобы JS выполнялся как можно раньше, но не раньше, чем вся DOM страницы будет на месте - это позволит проверять DOM, не дожидаясь загрузки потенциально медленных изображений.
Не гарантируется правильная работа. В этой статье объясняется, почему: snook.ca/archives/javascript/settimeout_solve_domcontentload ed
Почему не это:
<body>
<!-- various content -->
<script type = "text/javascript">
<!--
myInit();
-->
</script>
</body>
Если я правильно понимаю, myInit будет запущен, как только браузер попадет на страницу, что является последним в теле.
К сожалению, это простое решение не работает, если у меня нет контроля над страницей - например, при создании библиотеки JS, которая будет включена через тег <script>.
Замечательное кроссбраузерное решение, которое вы ищете… не существует… (представьте себе звук большой толпы, говорящей «ааааа…»).
DomContentLoaded - ваш лучший снимок. Вам все еще нужна техника polling для IE-старых.
Я нашел следующий пример кода на javascript.info, который вы можете использовать для охвата всех браузеров:
function bindReady(handler){
var called = false
function ready() {
if (called) return
called = true
handler()
}
if ( document.addEventListener ) { // native event
document.addEventListener( "DOMContentLoaded", ready, false )
} else if ( document.attachEvent ) { // IE
try {
var isFrame = window.frameElement != null
} catch(e) {}
// IE, the document is not inside a frame
if ( document.documentElement.doScroll && !isFrame ) {
function tryScroll(){
if (called) return
try {
document.documentElement.doScroll("left")
ready()
} catch(e) {
setTimeout(tryScroll, 10)
}
}
tryScroll()
}
// IE, the document is inside a frame
document.attachEvent("onreadystatechange", function(){
if ( document.readyState === "complete" ) {
ready()
}
})
}
// Old browsers
if (window.addEventListener)
window.addEventListener('load', ready, false)
else if (window.attachEvent)
window.attachEvent('onload', ready)
else {
var fn = window.onload // very old browser, copy old onload
window.onload = function() { // replace by new onload and call the old one
fn && fn()
ready()
}
}
}
Есть какие-нибудь новости по этому поводу? Этот ответ просидел здесь 2,5 года ... может быть, производители браузеров и стандарты теперь лучше работают?