Pro jQuery
Адам Фриман
Ожидание DOM
В главе 2 я разметил элемент script
в конце документа, так чтобы браузер создал все объекты в DOM до выполнения моего JavaScript кода. Эту проблему можно аккуратно обойти, используя jQuery. В листинге 5-6 показан соответствующий код.
Листинг 5-6: Ожидание DOM
<script type="text/javascript">
$(document).ready(function () {
// ...code to execute...
});
</script>
Вы вставляете переменную document
(о которой я говорил в главе 1) в $
функцию и вызываете метод ready
, перейдя к функции, которая должна быть выполнена, когда DOM загружен и готов к использованию. Тогда вы можете разместить элемент script
в любой части документа, абсолютно точно зная, что jQuery не даст функции быть выполненной преждевременно.
Заметка
Добавление
function
в методready
создает обработчик для jQuery событияready
. О jQuery событиях я подробно расскажу в главе 9. А сейчас, пожалуйста, просто примите как должное, чтоfunction
, которую вы передаете методуready
, будет вызвана тогда, когда документ загружен и DOM готов к использованию.
Забыли о функции
Распространенной ошибкой является пренебрежение частью function
этого чудесного блока кода, а происходит только включение ряда выражений JavaScript в метод ready
. Это не работает. Выражения выполняются браузером немедленно, а не тогда, когда готов DOM. Смотрите листинг 5-7.
Листинг 5-7: Обработчик события ready "упустил" функцию
...
<script type="text/javascript">
function countImgElements() {
return $("img").length;
}
$(document).ready(function () {
console.log("Ready function invoked. IMG count: " + countImgElements());
});
$(document).ready(
console.log("Ready statement invoked. IMG count: " + countImgElements())
);
</script>
...
В этом примере я дважды вызвал метод ready, один раз с function
, а один раз с обычным JavaScript выражением. В обоих случаях я вызвал функцию countImgElements
, которая возвращает число элементов img
, присутствующих в DOM. (Не думайте сейчас о том, как работает этот метод. О том, как обратиться к свойству length
, я расскажу позже в этой главе). Когда я загружаю документ, выполняется скрипт, и вот результат на консоли:
Ready statement invoked. IMG count: 0
Ready function invoked. IMG count: 6
Как вы видите, выражение без функции выполняется, когда подгружается документ и до того как браузер обнаружил элементы img
в документе и создал соответствующие DOM объекты.
Использование альтернативной записи
Если хотите, в качестве параметра $
функции jQuery вы можете задать свою функцию. Результат будет таким же, как и при использовании $(document).ready
. В листинге 5-8 представлен пример.
Листинг 5-8: Отсрочка выполнения функции до полной готовности DOM
...
<script type="text/javascript">
$(function () {
$("img:odd").mouseenter(function (e) {
$(this).css("opacity", 0.5);
}).mouseout(function (e) {
$(this).css("opacity", 1.0);
})
});
</script>
...
Отсрочка события ready
Вы можете управлять тем, когда сработает событие ready, используя метод holdReady
. Это может быть полезным, если вам нужно динамически подгружать внешние ресурсы (нестандартный и продвинутый прием). Метод holdReady
обязательно должен быть вызван прежде, чем сработает событие ready
, а затем событие сработает уже тогда, когда вам это нужно. В листинге 5-9 показан пример использования этого метода.
Листинг 5-9: Использование метода holdReady
...
<script type="text/javascript">
$.holdReady(true);
$(document).ready(function () {
console.log("Ready event triggered");
$("img:odd").mouseenter(function (e) {
$(this).css("opacity", 0.5);
}).mouseout(function (e) {
$(this).css("opacity", 1.0);
})
});
setTimeout(function () {
console.log("Releasing hold");
$.holdReady(false);
}, 5000);
</script>
...
В этом примере я вызвал метод holdReady
в начале элемента script
. В качестве аргумента я передал значение true
, указывая, что выполнение события ready
должно быть отложено. Потом я определил функцию, которая должна быть вызвана, когда сработает событие ready
(это тот же блок кода, которым я начал эту главу, он изменяет прозрачность некоторых рисунков).
И наконец, я использовал метод setTimeout
, чтобы вызвать функцию после 5000 миллисекунд. Эта функция вызывает метод holdReady
с аргументом false
, который говорит jQuery запустить событие ready
. Чистый эффект этого действа таков, что я отложил включение события ready
на пять секунд. Я добавил несколько сообщений по отладке, которые выводят следующий результат на консоль, когда документ загружен в браузер:
Releasing hold
Ready event triggered
Совет
Вы можете вызвать метод
holdReady
несколько раз, но чтобы событие сработало, число вызовов методаholdReady
с аргументомtrue
должно соответствовать такому же числу вызовов с аргументомfalse
.