Как уже говорилось в главе 15, каждому HTML_элементу в документе соответст_ вует DOM_элемент в дереве документа, и свойства этого JavaScript_объекта соот_ ветствуют атрибутам HTML_элемента. Это относится также к атрибутам обра_ ботчиков событий. Поэтому если в теге <input> имеется атрибут onclick, к ука_ занному в нем обработчику событий можно обратиться с помощью свойства on_ click объекта элемента формы. (Язык JavaScript чувствителен к регистру, поэтому независимо от регистра символов в имени HTML_атрибута JavaSсript_ свойство должно быть записано целиком в нижнем регистре.)
Так как значение HTML_атрибута, определяющего обработчик событий, являет_ ся строкой JavaScript_кода, можно предполагать, что соответствующее Java_ Sсript_свойство также представляет собой строку. Но это не так: при обращении посредством JavaScript_кода свойства обработчиков событий представляют со_ бой функции. Убедиться в этом можно с помощью простого примера:
<input type="button" value="Щелкни здесь"
onclick="alert(typeof this.onclick);">
Если щелкнуть на кнопке, откроется диалоговое окно, содержащее слово «func_ tion», а не слово «string». (Обратите внимание: в обработчиках событий ключе_ вое слово this ссылается на объект, в котором произошло событие. Позже мы об_ судим ключевое слово this.)
Чтобы назначить обработчик события элементу документа с помощью Java_ Script, установите свойство_обработчик события равным нужной функции. Рас_ смотрим, например, следующую HTML_форму:
На кнопку в этой форме можно сослаться с помощью выражения document.f1.b1, значит, обработчик события можно установить с помощью следующей строки кода:
Обратите особое внимание на последнюю строку: здесь после имени функции нет скобок. Чтобы определить обработчик события, мы присваиваем свойству_обра_ ботчику события саму функцию, а не результат ее вызова. На этом часто «споты_ каются» начинающие JavaScript_программисты.
В представлении обработчиков событий в виде JavaSсript_свойств есть два пре_ имущества. Во_первых, это сокращает степень смешения HTML_ и JavaScript_ кода, стимулируя модульность и позволяя получить более ясный и легко сопро_ вождаемый код. Во_вторых, благодаря этому функции_обработчики событий яв_ ляются динамическими. В отличие от HTML_атрибутов, которые представляют собой статичную часть документа и могут устанавливаться только при его созда_ нии, JavaSсript_свойства могут изменяться в любое время. В сложных интерак_ тивных программах иногда полезно динамически изменять обработчики собы_ тий, зарегистрированные для HTML_элементов.
Один небольшой недостаток определения обработчиков событий в JavaScript со_ стоит в том, что это отделяет обработчик от элемента, которому он принадлежит. Если пользователь начнет взаимодействовать с элементом документа до его пол_ ной загрузки (и до исполнения всех его сценариев), обработчики событий для элемента могут оказаться неопределенными.
В примере 17.1 демонстрируется, как назначить функцию обработчиком собы_ тия для нескольких элементов документа. Данный пример представляет собой простую функцию, определяющую обработчик события onclick для каждой ссылки в документе. Обработчик события запрашивает подтверждение пользо_ вателя, перед тем как разрешить переход по ссылке, на которой пользователь только что щелкнул. Если пользователь не дал подтверждения, функция_обра_ ботчик возвращает false, что не дает броузеру перейти по ссылке. Возвращаемые обработчиками событий значения обсуждаются в ближайших разделах.
Пример 17.1. Одна функция, много обработчиков событий
// Эта функция подходит для работы в качестве обработчика события
// onclick элементов <a> и <area>. Она использует ключевое слово this
// для обращения к элементу документа и может возвращать false
// для отмены перехода по ссылке.
function confirmLink() {
return confirm("Вы действительно хотите посетить " + this.href + "?");
}
// Эта функция выполняет цикл по всем гиперссылкам в документе и назначает
// каждой из них функцию confirmLink в качестве обработчика события.
// Не вызывайте ее до того, как документ будет проанализирован
// и все ссылки определены. Лучше всего вызвать ее из обработчика
// события onload тега <body>.
function confirmAllLinks() {
for(var i = 0; i < document.links.length; i++) { document.links[i].onclick = confirmLink;