Главная страница   /   5.4. Ожидание DOM (Pro jQuery

Pro jQuery

Pro jQuery

Адам Фриман

5.4. Ожидание 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.