Книга: JavaScript. Подробное руководство, 6-е издание

17.4. События загрузки документа

17.4. События загрузки документа

Теперь, когда мы познакомились с основами обработки событий в языке JavaScript, можно приступать к изучению подробностей, касающихся отдельных категорий событий. В этом разделе мы начнем с событий, возникающих при загрузке документа.

Большинству веб-приложений совершенно необходимо, чтобы веб-броузер извещал их о моменте, когда закончится загрузка документа и он будет готов для выполнения операций над ним. Этой цели служит событие «load» в объекте Window, и оно уже подробно обсуждалось в главе 13, где в примере 13.5 была представлена реализация вспомогательной функции onLoad(). Событие «load» возбуждается только после того, как документ и все его изображения будут полностью загружены. Однако обычно сценарии можно запускать сразу после синтаксического анализа документа, до того как будут загружены изображения. Можно существенно сократить время запуска веб-приложения, если начинать выполнение сценариев по событиям, отличным от «load».

Событие «DOMContentLoaded» возбуждается, как только документ будет загружен, разобран синтаксическим анализатором, и будут выполнены все отложенные сценарии. К этому моменту изображения и сценарии с атрибутом async могут продолжать загружаться, но сам документ уже будет готов к выполнению операций. (Отложенные и асинхронные сценарии обсуждались в разделе 13.3.1.) Это событие впервые было введено в Firefox и впоследствии заимствовано всеми другими производителями броузеров, включая корпорацию Microsoft, которая добавила поддержку этого события в IE9. Несмотря на приставку «DOM» в имени, это событие не является частью стандарта модели событий «DOM Level 3 Events», но оно стандартизовано спецификацией HTML5.

Как описывалось в разделе 13.3.4, в ходе загрузки документа изменяется значение свойства document.readyState. Каждое изменение значения этого свойства в IE сопровождается событием «readystatechange» в объекте Document, благодаря чему в IE это событие можно использовать для определения момента появления состояния «complete». Спецификация HTML5 стандартизует событие «readystatechange», но предписывает возбуждать его непосредственно перед событием «load», поэтому не совсем понятно, в чем заключается преимущество события «readystatechange» перед «load».

В примере 17.1 определяется функция whenReady(), близко напоминающая функцию onLoad() из примера 13.5. Функция, передаваемая функции whenReady(), вызывается (как метод объекта Document) сразу, как только документ будет готов к выполнению операций. В отличие от ранее представленной функции onLoad(), whenReady() ожидает появления событий «DOMContentLoaded» и «readystatechange» и использует событие «load» только как запасной вариант, на случай если она будет задействована в старых броузерах, не поддерживающих первые два события. Функция whenReady() будет использоваться в некоторых сценариях, следующих далее (в этой и в других главах).

Пример 17.1. Вызов функций, когда документ будет готов к выполнению операций

/*
* Передайте функции whenReady() свою функцию, и она вызовет ее (как метод
* объекта документа), как только завершится синтаксический анализ документа
* и он будет готов к выполнению операций. Зарегистрированные функции
* вызываются при первом же событии DOMContentLoaded, readystatechange или load.
* Как только документ станет готов и будут вызваны все функции,
* whenReady() немедленно вызовет все функции, которые были ей переданы.
*/
var whenReady = (function() { // Эта функция возвращается функцией whenReady()
  var funcs = []; // Функции, которые должны вызываться по событию
  var ready = false; // Получит значение true при вызове функции handler
  // Обработчик событий, который вызывается, как только документ
  // будет готов к выполнению операций
  function handler(e) {
    // Если обработчик уже вызывался, просто вернуть управление
    if (ready) return;
    // Если это событие readystatechange и состояние получило значение,
    // отличное от "complete", значит, документ пока не готов
    if (e.type==="readystatechange" && document.readyState !== "complete") return;
    // Вызвать все зарегистрированные функции.
    // Обратите внимание, что здесь каждый раз проверяется значение
    // свойства funcs.length, на случай если одна из вызванных функций
    // зарегистрирует дополнительные функции.
    for(var і = 0; і < funcs.length; i++) funcs[і].call(document);
    // Теперь можно установить флаг ready в значение true и забыть
    // о зарегистрированных функциях
    ready = true;
    funcs = null;
  }
  // Зарегистрировать обработчик handler для всех ожидаемых событий
  if (document.addEventListener) {
    document.addEventListener("DOMContentLoaded", handler, false);
    document.addEventListener("readystatechange", handler, false);
    window.addEventListener("load", handler, false);
  }
  else if (document.attachEvent) {
    document.attachEvent("onreadystatechange", handler);
    window.attachEvent("onload”, handler);
  }
  // Вернуть функцию whenReady
  return function whenReady(f) {
    if (ready)
      f.call(document); // Вызвать функцию, если документ готов 
    else
     funcs.push(f); // Иначе добавить ее в очередь,
  } // чтобы вызвать позже.
}());

Оглавление книги


Генерация: 1.724. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз