JavaScript: как написать $(документ). уже как событие без jquery
В jquery $(документ).ready(функция) или $ (функция), как я могу сделать то же самое без jquery, и мне нужно, чтобы браузер был совместимым, и разрешить прикрепить более одной функции.
Примечание: Дом готов!= Окно загрузки
7 ответов
Именно так jQuery оборачивает нужные вам функции - сниппету не нужен jQuery, и он совместим с разными браузерами. Я заменил все вызовы jQuery.ready() на yourcallback
- который вы должны определить.
Что здесь происходит:
- во-первых, функция
DOMContentLoaded
определяется, который будет использоваться при возникновении события DOMContentLoaded - это гарантирует, что обратный вызов вызывается только один раз. - проверка, если документ уже загружен - если да, немедленно запустить обратный вызов
- иначе вынюхивать
document.addEventListener
/document.attachEvent
) и привязать к нему обратные вызовы (разные для IE и обычных браузеров, плюс обратный вызов onload)
Отменено из jQuery 1.4.3, функции bindReady() и DOMContentLoaded:
/*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
// Cleanup functions for the document ready method
// attached in the bindReady handler
if ( document.addEventListener ) {
DOMContentLoaded = function() {
document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
//jQuery.ready();
yourcallback();
};
} else if ( document.attachEvent ) {
DOMContentLoaded = function() {
// Make sure body exists, at least, in case IE gets a little overzealous
if ( document.readyState === "complete" ) {
document.detachEvent( "onreadystatechange", DOMContentLoaded );
//jQuery.ready();
yourcallback();
}
};
}
// 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 );
// ^^ you may want to call *your* function here, similarly for the other calls to jQuery.ready
setTimeout( yourcallback, 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 );
window.addEventListener( "load", yourcallback, 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", yourcallback );
}
Это 51 строка чистого кода JavaScript, просто чтобы надежно зарегистрировать событие. Насколько я знаю, более простого способа не существует. Здесь мы покажем, для чего хороши обертки типа jQuery: они обертывают возможности перехвата возможностей и отвратительные проблемы совместимости, так что вы можете сосредоточиться на чем-то другом.
Самый маленький DOMReady код, когда-либо.
<html>
<head>
<script>
var ready = function (f) {
(/complete|loaded|interactive/.test(document.readyState)) ?
f() :
setTimeout(ready, 9, f);
};
</script>
</head>
<body>
<script>
ready(function () {
alert('DOM Ready!');
});
</script>
</body>
</html>
Это все, что вам нужно, если вы поддерживаете IE9+ и современные (2013) версии Chrome, FF, Safari и т. Д.
function ready(event) {
// your code here
console.log('The DOM is ready.', event);
// clean up event binding
window.removeEventListener('DOMContentLoaded', ready);
}
// bind to the load event
window.addEventListener('DOMContentLoaded', ready);
Вот метод, который я использую, который, кажется, работает надежно
function ready(func) {
var span = document.createElement('span');
var ms = 0;
setTimeout(function() {
try {
document.body.appendChild(span);
document.body.removeChild(span);
//Still here? Then document is ready
func();
} catch(e) {
//Whoops, document is not ready yet, try again...
setTimeout(arguments.callee, ms);
}
}, ms);
}
Довольно просто, он просто пытается добавить пустую <span>
элемент к document.body
, Если документ не "готов", будет выдано исключение, и в этом случае он попытается снова с новым setTimeout
вызов. Если исключение не выдается, вызывается функция обратного вызова.
Я был бы рад узнать, есть ли какие-либо проблемы с этим методом. Это хорошо сработало для меня, но я не проводил всестороннего тестирования, которое было бы естественным для любой популярной платформы Javascript.
Я видел много разных способов сделать это. Самый простой способ (я думаю, изначально предложенный yahoo) - просто вызвать функцию инициализатора после тега close body, немного навязчиво, но это одна строка.
редактировать
Событие DomReady не существует нативно в JavaScript. Вы можете реализовать свою собственную, следуя какой-то замечательной работе, проделанной такими людьми, как Дин Эдвардс, здесь и здесь с теми, кто у вас на месте, вы можете выполнить аналогичный процесс прикрепления событий к документу вместо окна.
Ознакомьтесь с ответом user83421 на Как добавить дополнительное событие window.onload в Javascript
Подведем итоги.
if (window.addEventListener) // W3C standard
{
window.addEventListener('load', myFunction, false); // NB **not** 'onload'
}
else if (window.attachEvent) // Microsoft
{
window.attachEvent('onload', myFunction);
}
У меня есть это после тега "закрыть тело" и до тега "закрыть HTML". и это работает довольно хорошо. Функция загрузки пресетов присваивает значения ширины, высоты и положения тэгам css div. полезно для разных размеров экрана.
document.onreadystatechange = function () {
if (document.readyState == "interactive") {
loadPresets();
}
}