Программный JavaScript_код, выполняющий модификации документа, в кото_ ром он содержится, как правило, должен запускаться лишь после того, как до_ кумент будет полностью загружен (детальное обсуждение этого вопроса вы най_ дете в разделе 13.5.7). Когда загрузка документа завершается, броузеры генери_ руют событие onload в объекте Window, и это событие обычно используется для за_ пуска программного кода, которому требуется доступ ко всему документу. Если веб_страница содержит несколько независимых модулей, которые должны за_ пускаться в ответ на событие onload, вам пригодится не зависящая от платформы вспомогательная функция, подобная представленной в примере 17.7.
Пример 17.7. Переносимый способ регистрации обработчиков события onload
/*
* runOnLoad.js: переносимый способ регистрации обработчиков события onload.
*
* Данный модуль определяет единственную функцию runOnLoad(),
* выполняющую регистрацию переносимым способом функций_обработчиков,
* которые могут вызываться только после полной загрузки документа,
* когда будет доступна стуктура DOM.
*
* Функциям, зарегистрированным с помощью runOnLoad(), не передается ни одного
* аргумента при вызове. Они вызываются не как методы какого_либо объекта
* и потому в них не должно использоваться ключевое слово this.
* Функции, зарегистрированные с помощью runOnLoad(), вызываются
* в порядке их регистрации. При этом нет никакой возможности отменить
* регистрацию функции после того, как она передана функции runOnLoad().
*
* В старых броузерах, не поддерживающих addEventListener() или attachEvent(),
* эта функция выполняет регистрацию с использованием свойства window.onload
* модели DOM уровня 0. Она будет работать некорректно в документах,
* где установлен атрибут onload в тегах <body> или <frameset>.
*/
function runOnLoad(f) {
if (runOnLoad.loaded) f(); // Если документ уже загружен, просто вызвать f().
else runOnLoad.funcs.push(f); // Иначе сохранить для вызова позднее
}
runOnLoad.funcs = []; // Массив функций, которые должны быть вызваны // после загрузки документа
450 Глава 17. События и обработка событий
runOnLoad.loaded = false; // Функции еще не запускались.
// Запускает все зарегистрированные функции в порядке их регистрации.
// Допускается вызывать runOnLoad.run() более одного раза: повторные
// вызовы игнорируются. Это позволяет вызывать runOnLoad() из функций
// инициализации для регистрации других функций.
runOnLoad.run = function() {
if (runOnLoad.loaded) return; // Если функция уже запускалась, ничего не делать for(var i = 0; i < runOnLoad.funcs.length; i++) {
try { runOnLoad.funcs[i](); }
catch(e) { /* Исключение, возникшее в одной из функций, не должно
делать невозможным запуск оставшихся */ }
}
runOnLoad.loaded = true; // Запомнить факт запуска.
delete runOnLoad.funcs; // Но не запоминать сами функции.
delete runOnLoad.run; // И даже забыть о существовании этой функции!
};
// Зарегистрировать метод runOnLoad.run() как обработчик события onload окна if (window.addEventListener)