Введение в события Javascript

Практически все JavaScript-приложения выполняют те или иные действия, откликаясь на различные события. 

Событие - это сигнал от браузера о том, что что-то произошло. 

Есть множество самых различных событий.
DOM-события, которые инициируются элементами DOM. Например, событие click происходит при клике на элементе, а событие mouseover - когда указатель мыши появляется над элементом,
События окна. Например событие resize - при изменении размера окна браузера, 
Другие события, например load, readystatechange. Они используются, скажем, в технологии AJAX.

Именно DOM-события связывают действия, происходящие в документе, с кодом JavaScript, тем самым обеспечивая динамический веб-интерфейс.
Назначение обработчиков

Для того, чтобы скрипт реагировал на событие - нужно назначить хотя бы одну функцию-обработчик. Обычно обработчики называют "on+имя события", например: onclick.

Нужно сразу отметить, что JavaScript - однопоточный язык, поэтому обработчики всегда выпоняются последовательно и в общем потоке. Это значит, что при установке обработчиков двух событий, которые возникают на элементе одновременно, например mouseover (мышь появилась над элементом) и mousemove (мышь двигается над элементом), их обработчики будут выполнены последовательно.

Существует несколько способов назначать обработчик на конкретное событие элемента. Все они представлены ниже.
Через атрибут HTML-тега

Обработчик события можно указать в виде inline-записи, прямо в атрибуте onсобытие. 

Например, для обработки события click на кнопке input, можно назначить обработчик onclick вот так:<input />


 Этот код в действии:



Можно назначить и функцию.

Например, пусть при клике на кнопку input запускается функция count_rabbits(). Для этого запишем вызов функции в атрибут onclick:
01    <html>
02     
03        <head>
04            <script >
05                function count_rabbits() {
06                    for(var ; i<; i++) {
07                       // оператор + соединяет строки
08                       alert("Из шляпы достали "+i+" кролика!")
09                    }
10                }
11             </script>
12        </head>
13     
14        <body>
15             <input />
16        </body>
17     
18    </html>


 Напомним, что имена атрибутов HTML-тегов нечувствительны к регистру, поэтому атрибут oNcLiCk сработает также, как onClick или onclick. 

Но если вы хотите придерживаться хорошего стиля (или спецификации XHTML), то имена тегов и их атрибуты должны быть указаны в нижнем регистре.
Когда использовать

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

У этого способа установки обработчика есть и минусы. Как только обработчик начинает занимать больше одной строки - читабельность резко падает. 

Впрочем, сколько-нибудь сложные обработчики в HTML никто не пишет. Вместо этого лучше устанавливать обработчики из JavaScript способами, которые будут представлены ниже.
Просто для простых задач
Смесь javascript-кода и HTML-разметки
Сложные обработчики писать сложно или невозможно
Через свойство объекта

Самый близкий родственник описанного выше способа - установка функции-обработчика через свойство onсобытие соответствующего элемента. Этот способ тоже будет работать в любом браузере с поддержкой JavaScript.

Для этого нужно:
получить элемент
назначить обработчик свойству on+имя

Вот пример установки обработчика события click на элемент с :document.getElementById('myElement').onclick = function() {
    alert('Спасибо')
}
<input />


 Этот код в действии:



 Стоит сразу обратить внимание на две детали:
Это именно свойство, а не атрибут. Поэтому, хотя технически и есть кроссбраузерные способы назначать обработчики через setAttribute, но лучше их даже не знать, а пользоваться прямым присвоением. 

Кроме того, как и все свойства объектов JavaScript, имя свойства onсобытие чувствительно к регистру символов и должно быть в нижнем регистре. 
Обработчик - не текст, а именно функция javascript. 

Когда браузер видит свойство on... в HTML-разметке - он создает функцию из содержимого кавычек. 

В этом смысле эти два кода работают одинаково:
Только HTML:<input />

HTML + JS:<input />
document.getElementById('button').onclick = function() {
     alert('Клик')
}

Все вызовы типа getElementById должны запускаться после описания соответствующего HTML-узла, а лучше - после окончания загрузки страницы. 

Иначе узел просто не будет найден. 

Конечно, можно и не создавать анонимную функцию, а использовать любую уже готовую:1    function doSomething() {
2        alert('Спасибо')
3    }
4     
5    document.getElementById('button').onclick = doSomething

Частая ошибка новичков

Обратите внимание - свойству присваивается именно сама функция-обработчик doSomething, а не doSomething():document.getElementById('button').onclick = doSomething


doSomething() - это результат запуска функции, а так как вызова return в ее коде нет, то этот результат будет undefined.

Сравните это со свойством. Там - наоборот, скобки нужны:<input />


 Это различие легко объяснить. Дело в том, что при назначении onclick в HTML браузер автоматически создает функцию-обработчик из содержимого кавычек. Получается, что последний пример - это по сути то же самое, что:document.getElementById('mybutton').onclick = function() {
     doSomething()  // внутри автосозданной функции
}

Когда использовать

Описанная установка обработчика через свойство - очень популярный и простой способ.

У него есть один недостаток: на элемент можно повесить только один обработчик нужного события.

Например:input.onclick = function() { alert(1) }
// ...
input.onclick = function() { alert(2) }  // заменит предыдущий

Удобный и надежный способ, работает из javascript
Только один обработчик на событие

Конечно, можно при назначении нового обработчика копировать предыдущий и запускать его самостоятельно. Но лучше использовать специальные методы назначения.
Специальные методы

Представленных выше методов недостаточно для случаев, которые возникают при разработке серьёзного JavaScript-приложения. 

Классический пример - установка обработчика на событие "содержимое окна загрузилось":1    // разные элементы интерфейса могут иметь интерес 
2    // в том, чтобы их вызвали при загрузке документа
3    window.onload = function() {
4       alert('Документ загружен!')
5    }

Если заведомо нет локальной переменной onload, то можно и не упоминать про window. Пустячок, но код немного короче. onload = function() { ... }


Существует два основных интерфейса для установки событий.
Решение Microsoft

Методы, предложенные Microsoft, работают только в браузерах Internet Explorer и Opera(она поддерживает метод Microsoft для лучшей совместимости).

Установка обработчика:element.attachEvent( "on"+имя события, обработчик)


 Удаление обработчика:element.detachEvent( "on"+имя события, обработчик)


 Например:1    var input = document.getElementById('b1')
2    var handler = function() {
3        alert('Спасибо!')
4    }
5    input.attachEvent( "onclick" , handler) // поставить обработчик
6    // .... 
7    input.detachEvent( "onclick", handler) // убрать обработчик

Частая ошибка новичков

Обратите внимание - установка и удаление обработчика оперируют одной и той же функцией handler.

Так было бы неправильно:1    input.attachEvent( "onclick" ,
2       function() {alert('Спасибо')}
3    )
4    // .... 
5    input.detachEvent( "onclick", 
6       function() {alert('Спасибо')}
7    )
8    // function(){} создает две разные функции


 Поэтому при назначении обработчика, если вы планируете его потом снимать - необходимо где-то сохранить указатель на функцию. 

Как уже говорилось ранее, вы можете установить несколько обработчиков на одно событие одного элемента:01    var myElement2 = document.getElementById("myElement2");
02    var handler = function() {
03        alert('Спасибо!');
04    }
05     
06    var handler2 = function() {
07        alert('Еще раз спасибо!');
08    }
09     
10    myElement2.attachEvent("onclick", handler);
11    myElement2.attachEvent("onclick", handler2);