JavaScript. Подробное руководство, 6-е издание, стр. 177
События, адресатом которых является элемент документа, часто распространяются вверх по дереву документа и этот процесс называется «всплытием». Если, например, пользователь щелкнет мышью на элементе <button>, событие «click» будет передано кнопке. Если это событие останется необработанным (и его распространение не будет остановлено) функцией, зарегистрированной в элементе кнопки, событие всплывет до элемента, в который вложена эта кнопка, и будет вызван обработчик события
<b>«click»,</b>Если для одного элемента требуется зарегистрировать более одного обработчика единственного события или если требуется написать модуль, который мог бы безопасно регистрировать обработчики событий, даже если для этих же событий и в этих же объектах уже были зарегистрированы обработчики другим модулем, можно воспользоваться другим приемом регистрации обработчиков. Большинство объектов, которые могут выступать в роли адресата события, имеют метод с именем
<b>addEventListener(),</b><b>window.addEventListener("load", function() {...}, false);</b><b>request.addEventListener("readystatechange", function() {...}, false);</b>Обратите внимание, что первым аргументом этой функции передается имя события. Несмотря на то что метод
<b>addEventListener()</b><b>attachEvent()</b><b>window.attachEvent("onload", function() {...});</b>Подробнее о функциях
<b>addEventlistener()</b><b>attachEvent()</b>Клиентские JavaScript-программы используют еще одну разновидность асинхронных извещений, которые, строго говоря, не являются событиями. Если свойству
<b>onerror</b><b>Window</b><b>setTimeout()</b><b>setlnterval()</b><b>setTimeout(),</b><b>setTimeout()</b><b>setlnterval()</b>Пример 13.5 демонстрирует применение функций
<b>setTimeout(), addEventListener()</b><b>attachEvent()</b><b>onLoad(),</b><b>onLoad()</b>Пример 13.5. <b>onLoad():</b>
<b>// Регистрирует функцию f, которая должна вызываться по окончании загрузки документа.</b><b>// Если документ уже загружен, функция f будет вызвана асинхронно и в кратчайшие сроки, </b><b>function onLoad(f) {</b><b> if (onLoad.loaded) // Если документ уже загружен</b><b> window.setTimeout(f, 0); // Вызвать f, как можно скорее</b><b> else if (window.addEventListener) // Стандартный метод регистрации событий </b><b> window.addEventListener("load", f, false); </b><b> else if (window.attachEvent) // В IE8 и в более ранних версиях</b><b> window.attachEvent("onload", f); // используется этот метод</b><b>}</b><b>// Сначала установить флаг, указывающий, что документ еще не загружен. </b><b>onLoad.loaded = false;</b><b>// И зарегистрировать функцию, которая сбросит флаг после загрузки документа. </b><b>onLoad(function() { onLoad.loaded = true; });</b>13.3.3. Модель потоков выполнения в клиентском JavaScript
Ядро языка JavaScript не имеет механизма одновременного выполнения нескольких потоков управления, и клиентский язык JavaScript не добавляет такой возможности. Стандарт HTML5 определяет механизм поддержки фонового потока выполнения «Web Workers» (подробнее об этом механизме рассказывается ниже), тем не менее JavaScript-код на стороне клиента выполняется в единственном потоке управления. Даже когда параллельное выполнение возможно, интерпретатор JavaScript не может обнаружить этот факт.
Выполнение в единственном потоке существенно упрощает разработку сценариев: можно писать программный код, пребывая в полной уверенности, что два обработчика событий никогда не запустятся одновременно. Можно манипулировать содержимым документа, точно зная, что никакой другой поток выполнения не попытается изменить его в то же самое время, и вам никогда не придется беспокоиться о блокировках, взаимоблокировках или о состояниях гонки за ресурсами при разработке своих программ.
Выполнение в единственном потоке означает, что веб-броузер должен прекратить откликаться на действия пользователя на время выполнения сценария или обработчика события. Это накладывает определенные требования: сценарии и обработчики событий в JavaScript не должны исполняться слишком долго. Если сценарий производит объемные и интенсивные вычисления, это вызовет задержку во время загрузки документа, и пользователь не увидит его содержимое, пока сценарий не закончит свою работу. Если продолжительные по времени операции выполняются в обработчике события, броузер может оказаться неспособным откликаться на действия пользователя, заставляя его думать, что программа «зависла». [29] (