Лекция

Тема: «Работа с событиями в JavaScript»

План

1. Способы назначения обработчиков событий.

2. События окна

3. Объект события, отмена действий по умолчанию

4. Делегирование событий

5. Управление порядком обработки

6. Основные события и их параметры

 

1. Способы назначения обработчиков событий.

Для реакции на действия посетителя и внутреннего взаимодействия скриптов существуют события.

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

Существует много видов событий.

 

- DOM-события, которые инициализируются элементами DOM. Например: click происходит, когда кликнули на элемент, mouseover — когда на элемент наводится мышь, focus — когда посетитель фокусируется на элементе. Событие keydown — когда посетитель нажимает клавишу.

 

- События для окна браузера. Например, resize — когда изменяется размер окна.

 

- События загрузки файла/документа: load, readystatechange, DOMContentLoaded

 

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

 

Назначение обработчиков событий

 

Есть несколько способов назначить событию обработчик.

·                    Использование атрибута HTML

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

Например, чтобы прикрепить click-событие к input кнопке, можно присвоить обработчик onclick, вот так:

 

<input id="b1" value="Нажми меня" onclick="alert('Спасибо!')" type="button"/>

 

При клике мышкой на кнопке выполнится код, указанный в атрибуте onclick.

Однако в разметке пишутся только очень простые обработчики. Если нужно сделать что-то сложное, то имеет смысл описать это в функции, и в обработчике вызвать её.

Следующий пример по клику запускает функцию countRabbits().

 

<!DOCTYPE HTML>

<html>

<head>

    <meta charset="utf-8">

    <script>

        function countRabbits()

        {

            for(var i=1; i<=3; i++)

                alert("Кролик номер " + i);

        }

    </script>

</head>

<body>

    <input type="button" onclick="countRabbits()" value="Считать кроликов!"/>

</body>

</html>

 

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

·                    Использование свойства DOM-объекта

Можно назначать обработчик, используя свойство DOM-элемента on<событие>.

Пример установки обработчика click элементу с id="myElement":

 

<input id="myElement" type="button" value="Нажми меня"/>

<script>

    var elem = document.getElementById('myElement');

    elem.onclick = function()

                   {

                       alert('Спасибо');

                   }

</script>

 

Если обработчик задан через атрибут, то соответствующее свойство появится у элемента автоматически. Браузер читает HTML-разметку, создаёт новую функцию из содержимого атрибута и записывает в свойство onclick.

Первичным является именно свойство, а атрибут — лишь способ его инициализации.

Эти два примера кода работают одинаково:

Только HTML:

 

<input type="button" onclick="alert('Клик!')" value="Кнопка"/>

 

HTML + JS:

 

<input type="button" id="button" value="Кнопка"/>

<script>

    document.getElementById('button').onclick = function()

                                                {

                                                    alert('Клик!');

                                                }

</script>

 

Обработчиком можно назначить уже существующую функцию:

 

function sayThanks()

{

    alert('Спасибо!');

}

document.getElementById('button').onclick = sayThanks;

 

Обратите внимание, что функция должна быть присвоена свойству как sayThanks, а не sayThanks():

 

document.getElementById('button').onclick = sayThanks;

 

А вот в разметке как раз скобки нужны:

 

<input type="button" id="button" onclick="sayThanks()"/>

 

Названия свойств регистрозависимы, поэтому on<событие> должно быть написано в нижнем регистре. Свойство ONCLICK работать не будет.

 

Доступ к элементу, this

 

Внутри обработчика события this ссылается на текущий элемент. Это можно использовать, чтобы получить свойства или изменить элемент.

В коде ниже абзац  р выводит свое содержимое, используя this.innerHTML:

 

<p onclick="alert(this.innerHTML)">Нажми меня</p>

 

Назначение нескольких событий

 

Фундаментальный недостаток описанных способов назначения обработчика — невозможность повесить несколько обработчиков на одно событие.

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

При этом новый обработчик будет затирать предыдущий. Например, следующий код на самом деле назначает один обработчик — последний:

 

input.onclick = function() { alert(1); }

input.onclick = function() { alert(2); } // заменит предыдущий обработчик

 

Существует специальный метод назначения обработчиков:

 

element.addEventListener('событие', handler, false);

 

И метод удаления обработчика:

 

element.removeEventListener('событие', handler, false);

 

Пример:

 

//пусть имеется функция

function func() { ... }

//добавим эту функцию для события onclick элемента

elem.addEventListener( "click" , func, false)

//удалим созданный ранее обработчик

elem.removeEventListener( "click", func, false)

 

Обратите внимание, что имя функции указывается без кавычек и круглых скобок.

 

Пример. Описать две функции. Для каждого изображения img назначить первую функцию в качестве обработчика события click. Позже в это событие добавить вторую функцию.

 

function f1()

{

    //увеличим ширину картинки на 10px

    this.style.width+='10px';

}

 

function f2()

{

    //добавим вокруг элемента рамку

    this.style.cssText='border: 3px solid red;';

}

 

//получаем массив всех изображений

var pict=document.getElementsByTagName('img');

//организовываем цикл по массиву

for (var i=0; i< pict.length; i++)

    //каждому изображению в событие click

    //назначаем  обработчиком функцию f1

    pict[i].addEventListener('click', f1, false);

 

. . .

 

//ниже каждому изображению в событие click

//добавляем функцию f2

for (var i=0; i< pict.length; i++)

    pict[i].addEventListener('click', f2, false);

 

//теперь при щелчке на изображении

//по очереди выполняться обе функции

 

При таком добавлении/удалении обработчиков нужно учитывать следующее:

 

- можно поставить столько обработчиков, сколько вам нужно;

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

 

2. События окна

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

 

var div=document.getElementById('div1');

 

может на сработать, если команда выполниться раньше, чем на страницу будет загружен элемент с id='div1'.

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

·                    Первый метод - разместить код скрипта внизу страницы. Пока браузер дойдет до кода и начнет выполняться, страница будет загружена и все элементы будут доступны. Такой метод не является предпочтительным, так как код скриптов не принято оформлять внизу, тем более что страница может быть довольно объемной, и скрипт будет размещаться далеко от начала страницы.

·                    Второй метод - поместить весь код скрипта в событие window.onload. Данной событие сработает после полной загрузки станицы, когда все дерево DOM сформировано и доступно для обработки. В этом случае код скрипта можно оформить в разделе head страницы, как это принято в большинстве случаев; или вынести в отдельный файл *.js, который можно подключить на страницу.

Пример оформления кода скрипта по второму способу внутри раздела head:

 

<head>

    . . .

    <script type='text/javascript'>

        window.onload = function()

        {

            //здесь размещают весь код

        }

    </script>

    . . .

</head>

 

Пример оформления скрипта в отдельном файле. Например, файл script.js имеет структуру:

 

window.onload = function()

{

    //здесь размещают весь код

}

 

В разделе head страницы подключите созданный файл

 

<head>

    . . .

    <script src='script.js'></script>

    . . .

</head>

 

 

Также объект window имеет событие

·                    window.onbeforeunload - возникает при попытке закрыть или перезагрузить страницу. В этом событии можно выдать запрос на выполнение операции и позволить пользователю подтвердить или отменить действие. Код события должен оформляться так:

window.onbeforeunload = function()

                        {

                            return 'текст-запрос на выход';

                        }

 

3. Объект события, отмена действий по умолчанию

Чтобы корректно обработать событие, иногда недостаточно знать о том, что это «клик» или «нажатие клавиши». Могут понадобиться детали: координаты курсора, введённый символ и другие, в зависимости от события.

Эти детали браузер записывает в «объект события», к которому может обратиться обработчик. Некоторые свойства объекта события для события onclick:

 

- event.type — тип события, равен click.

- event.target — элемент, по которому кликнули.

- event.clientX / event.clientY - координаты курсора в момент клика, относительно окна. и т.д.

 

То есть каждое событие имеет некоторый параметр-объект event, с помощью которого можно получить доступ к другим параметрам события.

Для примера:

 

element.onclick = function(event)

{

    alert(event.clientX); //вывести координату клика

};

 

Однако, браузер  IE8 не имеет параметра event, а вместо него создает собственный объект window.event.

Работает это так:

 

element.onclick = function()

{

    //window.event - объект события

    alert( window.event.clientX );

};

 

Так как нужно стремиться к созданию кроссбраузерных скриптов, то универсальным решением для получения объекта события будет код вида:

 

element.onclick = function(event)

{

    //в переменную записываем ссылку на параметр события

    //это будет или event (если браузер на IE8)

    //или window.event (если браузер IE8)

    var event = event || window.event; // Теперь event - объект события во всех браузерах.

    alert(event.clientX );

};

 

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

 

Наследование событий

 

Если событие назначено некоторому элементу дерева DOM и этот элемент имеет вложенные элементы, то данное событие автоматически назначается и всем вложенным элементам. При этом нужно понимать, что для обращения к активному элементу с помощью this недопустимо, так как это имя указывает на тот элемент, для которого этот обработчик назначен, то есть для самого верхнего элемента.

 

Пример. Пусть имеется структура вида:

 

<html>

<head>

<script type="text/javascript">

    //весь код выполняется после полной загрузки содержимого окна

    window.onload = function()

    {

 

        //получаем ссылку на блок с id='d1'       

        var d=document.getElementById('d1');

        //назначаем для блока обработчик события click       

        d.onclick = function()

        {

            //для текущего элемента меняем цвет фона       

            this.style.cssText='background-color: yellow;';

        }

    }

</script>

</head>

<body>

    <div id='d1'>Первый блок

        <div id='d1'>Второй блок

            <div id='d1'>Третий блок</div>

        </div>

    </div>

</body>

</html>

 

Если открыть страницу в браузере и щелкнуть по третьему (самому вложенному) или второму блоку, то закрасится первый. Это происходит за счет того, что this всегда ссылается на самый верхний элемент.

Если нужно выполнить функцию только для конкретного элемента, то параметр this нужно заменить на event.target. При этом браузер IE не имеет параметра event.target, а использует параметр event.srcElement. Универсальный способ получения этого параметра для всех браузеров будет рассмотрен ниже.

 

Изменим предыдущий пример:

 

<html>

<head>

<script type="text/javascript">

    //весь код выполняется после полной загрузки содержимого окна

    window.onload = function()

    {

 

        //получаем ссылку на блок с id='d1'       

        var d=document.getElementById('d1');

        //назначаем для блока обработчик события click       

        d.onclick = function()

        {

            //получаем ссылку на элемент, по которому щелкнули

            var elem = event.target || event.srcElement;           

            //для полученного объекта меняем цвет фона       

            elem.style.cssText='background-color: yellow;';

        }

 

    }

</script>

</head>

<body>

    <div id='d1'>Первый блок

        <div id='d1'>Второй блок

            <div id='d1'>Третий блок</div>

        </div>

    </div>

</body>

</html>

 

Данный пример будет закрашивать только тот блок, на котором кликнет пользователь.

 

Действия по умолчанию

 

В браузерах некоторые элементы имеют обработчики события по умолчанию. Например:

 

- при щелчке на гиперссылке выполняется переход по указанному адресу;

- при переходе в текстовое поле и вводе текста начинают отображаться введенные символы и т.д.

 

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

 

return false;

 

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

 

Пример. Пусть имеется текстовое поле, в которое нельзя ввести текст:

 

<input type="text" name="t1" size="20" onkeypress="return false;" />

 

Пример. Пусть имеется две гиперссылки, при щелчке на http://google.ru стандартный переход по адресу не выполняется, и выдается сообщение. Обработчик зададим через свойство элемента.

 

<html>

<head>

<script type="text/javascript">

    //весь код выполняется после полной загрузки содержимого окна

    window.onload = function()

    {

 

        //получаем ссылку на гиперссылки      

        var a=document.getElementsByTagName('a');

        

        //в цикле найдем гиперссылку, указывающую на google.ru

        for (var i=0; i<a.length; i++)

            //если адрес очередной ссылки google.ru           

            if (a[i].href='http://google.ru/')

            {

                //запоминаем эту ссылку в переменную g               

                var g=a[i];

                //завершаем работу цикла               

                break;

            }

 

        //для найденной гиперссылки присвоим обработчик

        g.onclick = function()

        {

            //выдаем сообщение

            alert ('Ссылка временно не работает');           

            //отменяем действие по умолчанию

            //переход по адресу не произойдет

            return false;

        }

    }

</script>

</head>

<body>

    <p>

        <a href='http://google.ru' target="_blank">Ссылка на сайт</a>

    </p>  

    <p>

        <a href='http://yandex.ru' target="_blank">Ссылка на сайт</a>

    </p>

</body>

</html>

 

Пример. Для всей страницы запретить выделение ее содержимого. Обработчик присвоим через свойство.

 

<head>

<script type="text/javascript">

    //весь код выполняется после полной загрузки содержимого окна

    window.onload = function()

    {

        //для тега body (вся страница) присвоим один код в двух событиях

        //первое событие для основной группы браузеров

        //второе для IE              

        document.body.onmousedown = document.body.onselectstart = function()

        {

            return false;

        }
                    }

</script>

</head>

4. Делегирование событий

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

Вместо этого, назначьте один обработчик общему родителю. Из него можно получить целевой элемент event.target, понять на каком потомке произошло событие и обработать его.

Эта техника называется делегированием и очень активно применяется в современном JavaScript.

 

Параметр event.target - это еще один из доступных параметров в любом событии. Данный параметр есть у большинства браузеров. Отличием является браузеры IE, у которых этот параметр записывается как event.srcElement. Следовательно, чтобы получить ссылку на целевой объект события для всех браузеров, нужно использовать команду:

 

var target = event.target || event.srcElement;

 

Пример. Пусть имеется структура списков для создания раскрывающегося меню. По умолчанию вложенные раскрывающиеся списки скрыты с помощью стиля display:none.

При щелчке на пункте меню нужно отображать/скрывать вложенный список. Для того, чтобы не "вешать" обработчик на каждый пункт меню мы "навесим" его на главный список с помощью механизма делегирования.

 

<html>

<head>

    <!--в стилях описан класс для скрытия подменю-->   

    <style type="text/css">

        .submenu {

        display:none;

        }

    </style>

    <script type="text/javascript">

        //весь код скрипта начинает выполняться после

        //загрузки всего содержимого окна       

        window.onload = function()

        {

           

            //получаем ссылку на главное меню (с id="menu")        

            var m=document.getElementById('menu');
                //для всего меню задаем обработчик события click         

            m.onclick = function()

            {
                    //получаем ссылку на элемент,

                //по которому кликнули мышью        

                var target = event.target || event.srcElement;
                    //если этот элемента имеет тег
li (команда меню)       

                if (target.tagName=='LI')
                        //проверяем следующий за ним элемент

                    //(а это ul со списком подпунктов меню)

                    //если свойство display списка не задано (взято из стиля)    

                    if (target.nextSibling.nextSibling.style.display=='')
                            //задаем этому свойству значение видимости

                        target.nextSibling.nextSibling.style.display='block'

                    //иначе возвращаем видимость в исходное состояние
                        else
                            target.nextSibling.nextSibling.style.display='';

            }

        }
        </script>

</head>


    <body>
        <ul id="menu">

    <li>Группа 1</li>

    <ul class="submenu">

<li>Команда 1.1</li>

<li>Команда 1.2</li>

    </ul>

    <li>Группа 2</li>

    <ul class="submenu">

<li>Команда 2.1</li>

<li>Команда 2.2</li>

    </ul>

    </ul>

</body>

</html>

 

Пример. Пусть имеется таблица с заголовками (th) и обычными ячейками данных. Если пользователь кликает на ячейках заголовков, то они окрашиваются одним цветом, а при клике на ячейках с данными - другим цветом. Повторный щелчок на ячейках возвращает исходный цвет.

Для таблицы присвоим один обработчик события click, в котором распознаются эти ячейки и выполняются соответствующие действия.

 

<html>

<head>

    <script type="text/javascript">

        //весь код скрипта выполнится после завершения содержимого окна

        window.onload = function()

        {

            //получаем ссылку на первую таблицу

            var t=document.getElementsByTagName('table')[0];

            //для таблицы задаем обработчик события click

            t.onclick = function()

            {

                //получаем ссылку на объект,

                //на котором выполнен клик

                var target = event.target || event.srcElement;

 

                //если кликнули на элементе с тегом th

                if (target.tagName == 'TH')

                    //переключаем цвет на желтый/исходный

                    target.style.backgroundColor = target.style.backgroundColor==''?'yellow':'';

                //иначе если кликнули на элементу с тегом td

                else if (target.tagName == 'TD')

                    //переключаем цвет на голубой/исходный

                    target.style.backgroundColor = target.style.backgroundColor==''?'cyan':'';

            }

        }

    </script>

</head>

 

<body>

    <table border="1" >

        <th>№ п/п</th>

        <th>Фамилия</th>

        <th>Имя</th>

        <th>Дата рождения</th>

        <tr>

            <td>1</td>

            <td>Иванов</td>

            <td>Сергей</td>

            <td>10.05.1992</td>

        </tr>

        <tr>

            <td>2</td>

            <td>Сидоров</td>

            <td>Евгений</td>

            <td>25.01.1987</td>

        </tr>

    </table>

</body>

</html>

 

5. Управление порядком обработки

В каждом окне выполняется только один главный поток, который занимается выполнением JavaScript, отрисовкой и работой с DOM.

Он выполняет команды последовательно и блокируется при выводе модальных окон, таких как alert.

Есть и другие потоки, например для сетевых коммуникаций, поэтому скачивание файлов может продолжаться пока основной поток ждёт реакции на alert. Но это скорее исключение, чем правило.

 

Асинхронные события

 

Большинство событий — асинхронны. Когда происходит асинхронное событие, оно попадает в очередь.

Внутри браузера существует главный внутренний цикл, который проверяет очередь и обрабатывает события, запускает соответствующие обработчики и т.п.

Все асинхронные события обрабатываются последовательно.

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

 

Использование setTimeout / setInterval

 

Вызов функции, запланированной setTimeout/setInterval, когда придёт время, добавляется в ту же самую очередь событий.

Конструкция setTimeout позволяют выполнить указанную функцию не сразу, а через заданное время.

 

Пример. Вывести сообщение через 5 секунд.

 

<script type="text/javascript">

    setTimeout (function()

                {

                    alert('Приветствуем Вас на сайте');

                },5000);

</script>

 

Конструкция setInterval аналогичен предыдущему примеру, только функция выполняется периодически через заданный интервал времени (аналог таймера).

Повторение выполняется до закрытия страницы или до вызова инструкции clearInterval().

 

Пример. Выдать с интервалом в 2 секунды 5 раз окно с сообщением.

 

<script type="text/javascript">

    //счетчик повторов

    var k=0;

    //сохраняем идентификатор запуска таймера

    var id = setInterval (function()

                          {

                            //выдаем сообщение

                            alert ('Приветствуем Вас на сайте');

                            //наращиваем счетчик повторов

                            k++;

                            //если счетчик равен 5

                            //останавливаем счетчик с идентификатором id

                            if (k==5)

                                clearInterval(id);

                          },2000);

</script>

 

Как было сказано выше, основной набор событий в браузере асинхронный - выполняемый в порядке очереди. Однако существуют синхронные события. Например, если выполняется какое-то событие, а пользователь в это время щелкнет мышью в поле на форме, то браузер не ждет окончания выполнения и ставит курсор в поле сразу, т.е. событие выполняется синхронно.

Еще одна задача связана с тем, что все события всплывают: сначала выполняется событие самого элемента, а затем событие его родителя. Существует возможность изменить порядок выполнения: сначала родитель, а затем сам элемент.

 

Для того, чтобы синхронное событие сделать асинхронным (поставить его в очередь) или, чтобы отложить выполнение события элемента до выполнения события родителя, такое событие нужно запланировать через конструкцию:

 

setTimeout(function(), 0);

 

Пример. Пусть имеется текстовое поле. Необходимо вводимый текст заменять на заглавные буквы.

 

<html>

<head>

    <script type="text/javascript">

        //весь код выполняется после загрузки содержимого окна  

        window.onload = function()

                        {

                            //получаем ссылку на первый элемент input

                            var i = document.getElementsByTagName('input')[0];

                            //для элемента назначаем обработчик события click                       

                            i.onkeydown = function()

                                          {

                                            //конвертируем содержимое поля к верхнему регистру                       

                                            i.value = i.value.toUpperCase();

                                          }

 

                        }

    </script>

</head>

 

<body>

    <input type="text" name="T1" size="20" />

</body>

</head>

 

Если запустить такой пример, то вы увидите, что последний вводимый символ не заменяется, потому что вначале делается замена, а только потом символ появляется в поле.

Для решения проблемы нужно отложить процесс замены до появления символа. Нужно поместить код функции в структуру setTimeout (function(), 0).

Пример нужно записать так:

 

<html>

<head>

    <script type="text/javascript">

    //весь код выполняется после загрузки содержимого окна  

        window.onload = function()

                        {

                          //получаем ссылку на первый элемент input   

                          var i = document.getElementsByTagName('input')[0];

                          //для элемента назначаем обработчик события click         

                          i.onkeydown = function()

                                        {

                                           //помещаем код обработчика в конструкцию setTimeout                       

                                           setTimeout (function()

                                                       {

                                                          i.value = i.value.toUpperCase();

                                                       },0)

                                        };

 

                        }

    </script>

</head>

 

<body>

    <input type="text" name="T1" size="20" />

</body>

</head>

 

Пример. Пусть имеется блок DIV#d1, а в нем еще один вложенный блок DIV#d2. При щелчке на любом из блоков вначале появляется рамка вокруг внешнего блока, а затем через 1 секунду рамка вокруг внутреннего блока.

 

<html>

<head>

    <script type="text/javascript">

    //весь код выполняется после загрузки окна

    window.onload = function()

                    {

                        //получаем ссылку на блок с id='d1'

                        var d = document.getElementById('d1');

                        //для блока задаем обработчик для события click

                        d.onclick = function()

                                    {

                                        //вокруг главного блока рисуем рамку

                                        this.style.cssText = 'border: 1px solid red';

                                        //получаем ссылку на элемент, на котором кликнули мышью

                                        var target = event.target || event.srcElement

                                       

                                        //если щелкнули на главном блоке

                                        if (target.id=='d1')

                                            //меняем текущий элемент на дочерний блок

                                            //(первый потомок в главном блоке)

                                            target = target.children[0];

                                        //задаем рисование рамки вокруг этого элемента через секунду

                                        setTimeout(function()

                                                   {

                                                    target.style.cssText = 'border: 1px solid red';

                                                   },1000);

                                    }

 

                    }

    </script>

</head>

 

<body>

    <div id="d1">

        Первый блок

        <div id="d2">

            Второй блок

        </div>

    </div>

</body>

</html>

 

6. Основные события и их параметры

В этом разделе рассмотрим события и их параметры.

·                    focus

Событие focus вызывается тогда, когда пользователь фокусируется на элементе, например кликает на INPUT или перемещается на него клавишей TAB. В данном событии можно, например, выполнить код подсветки поля (хотя это же можно сделать с помощью CSS).

Элементы, на которые можно установить фокус имеют собственный метод focus(), который позволяет программно установить курсор на элемент.

 

Пример. Написать код, который при загрузке страницы поставит курсор в первое поле input на странице.

 

document.getElementsByTagName('input')[0].focus();

 

Когда пользователь переходит по элементам клавишей TAB, то порядок перехода можно задавать, присваивая в тегах элементов атрибут tabindex="число". При этом элемент с tabindex="0" будет последним в цепочке перехода, а на элементы с tabindex="-1" будут недоступны для перехода.

·                    blur

Событие blur возникает при потере фокуса элементом. В этом событии можно, например, проверить правильность заполнения поля.

Пример. Если в первом поле не число, выдать сообщение и поставить курсор обратно в поле.

 

//получаем ссылку на поле

var i = document.getElementsByTagName('input')[0];

//для поля задаем обработчик для события blur

i.onblur = function()

{

//если в поле не число   

if (isNaN(this.value))

    {

        //выдаем сообщение       

        alert('Можно ввести только число. Повторите...');

        //ставим фокус в поле       

        this.focus();

    }

}

·                    change

Событие change происходит при изменении значения элемента формы. По стандарту, оно должно происходить после того, как элемент теряет фокус.

В реальности оно так и происходит для текстовых элементов.

Например, пока вы набираете что-то в текстовом поле ниже — события нет. Но как только вы уведёте фокус на другой элемент, например, нажмёте кнопку -  произойдет событие onchange (аналог события blur).

Данное событие часто применяется для выпадающих списков <select></select>, которое происходит при каждом выборе значения.

Пример. Пусть имеется список. При каждом выборе значения из списка нужно выдать сообщение с выбранным текстом.

 

<html>

<head>

    <script type="text/javascript">

        //работа кода выполняется после загрузки окна

        window.onload = function()

        {

 

            //получаем ссылку на первый список на странице

            var s = document.getElementsByTagName('select')[0];

            //для списка присваиваем обработчик события change

            s.onchange = function()

            {

                //выдаем текст выбранного элемента в списке

                alert(this.options[this.selectedIndex].text);

            }

        }

    </script>

</head>

 

<body>

    <select name="d1" size="1">

        <option>1</option>

        <option>2</option>

        <option>3</option>

    </select>

</body>

</html>

·                    input

Событие input срабатывает тут же при изменении значения текстового элемента и поддерживается всеми браузерами, кроме IE<9.

Пример. Пусть имеется текстовое поле, а за ним вставка span#result. В поле можно ввести 70 символов. Написать код, который при вводе или удалении текста показывает количество оставшихся символов.

 

<html>

<head>

    <script type="text/javascript">

        //код выполняется после загрузки окна

        window.onload = function()

        {

            //получаем ссылку на первое поле на странице

            var i = document.getElementsByTagName('input')[0];

            //получаем ссылку на наш фрагмент для вывода результат (id='result')

            var s = document.getElementById('result');

           

            //для поля задаем обработчик события input

            i.oninput = function()

            {

                //выдаем оставшееся количество символов

                s.innerHTML = 'Осталось символов - '+(70 - this.value.length);

            }

        }

    </script>

</head>

 

<body>

    <input type="text" size="70" maxlength="70"/>

    <span id="result">Осталось символов - 70</span>

</body>

</html>

 

События мыши

 

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

·                    click

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

·                    dblclick

Событие возникает при двойном щелчке на элементе.

·                    contextmenu

Событие возникает при щелчке на элементе правой кнопкой. По умолчанию приводит к стандартному действию появления контекстного меню. Это действие можно отменить (см. выше как отменить стандартные действия).

·                    mousedown, mouseup

События наступают при нажатии или отпускании кнопки мыши

·                    mouseover

Возникает, когда указатель мыши появляется над элементом

·                    mouseout

Событие возникает, когда указатель мыши уходит с элемента.

·                    mousemove

Возникает при движении указателя мыши по элементу.

 

Пример. Пусть при наведении мыши на абзац он окрашивается одним цветом, а при уходе - другим. Этот же эффект проще реализовать с помощью CSS  (:hover).

 

<html>

<head>

    <script type="text/javascript">

    //код выполняется после загрузки окна

    window.onload = function()

    {

        //получаем массив всех абзацев

        var p = document.getElementsByTagName('p');

        //в цикле проходим по массиву абзацев

        for (var i=0; i<p.length; i++)

        {

            //для каждого абзаца указываем обработчик события mouseover

            p[i].onmouseover = function()

            {

                //меняем цвет абзаца на желтый

                this.style.backgroundColor = 'yellow';

            };

           

            //для каждого абзаца указываем обработчик события mouseout

            p[i].onmouseout = function()

            {

                //меняем цвет абзаца на исходный

                this.style.backgroundColor = '';

            };

        }

    }

    </script>

</head>

 

<body>

    <p>Абзац 1</p>

    <p>Абзац 2</p>

    <p>Абзац 3</p>

    <p>Абзац 4</p>

</body>

</html>

 

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

 

<html>

<head>

    <script type="text/javascript">

    //код выполняется после загрузки окна

    window.onload = function()

    {

        //получаем ссылку на первое изображение

        var pict = document.getElementsByTagName('img')[0];

        //для изображения указываем обработчик события contextmenu

        pict.oncontextmenu = function()

        {

            //подавляем стандартное действие (выдачу контекстного меню)

            return false;

        };

    }

    </script>

</head>

 

<body>

   

<img src="pict.jpg" width="200px" />

</body>

</html>

 

Каждое событие мыши имеет ряд параметров, которые доступны через параметр event.

·                    event.which

Позволяет распознать кнопку мыши: 1 - левая, 2 - средняя, 3 - правая. На практике параметр используется редко, так как для левой кнопки есть события click, а для правой кнопки contextmenu.

·                    event.shiftKey, event.ctrlKey, event.altKey

Позволяет распознать специальные клавиши, которые нажаты во время возникновения события. Например, для проверки нажатия сочетания Ctrl + Shift можно ввести код:

 

if (event.shiftKey && event.ctrlKey)

·                    event.clientX, event.clientY

Координаты мыши относительно окна страницы.

·                    event.pageX, event.pageY

Координаты мыши относительно документа, включая прокрутку.

·                    event.target

Элемент, на котором возникло событие мыши.

·                    event.relatedTarget

Данный параметр имеет разный смысл в разных событиях. В событии mouseover он указывает на элемент, с которого пришел указатель мыши. В событии mouseout он указывает на элемент, на который пришел указатель мыши.

 

События клавиатуры

 

При просмотре страницы пользователь может нажимать клавиши клавиатуры, генерируя тем самым события, которые могут обрабатываться в коде.

При работе с клавиатурой могут возникать следующие события:

·                    keydown

Событие возникает при нажатии клавиши

·                    keyup

Событие возникает при отпускании клавиши

·                    keypress

Событие возникает при нажатии символьной клавиши. При нажатии специальных клавиш (F1-F12, TAB, PgUp и т.д.) данное событие не возникает.

 

Как и в других событиях через параметр-объект event можно получить доступ к другим параметрам.

·                    event.target

Позволяет определить элемент, на котором возникло событие

·                    event.keyCode

В событиях keydown и keyup позволяет распознать код нажатой клавиши. Не путать с кодом символа. Все клавиши имеют числовые коды, которые можно узнать по специальным таблицам. Для буквенно-цифровых клавиш, код можно узнать по коду заглавной латинской буквы этой клавиши или по коду цифры:  "символ".charCodeAt(0).

Пример.

 

Код клавиши "s/ы" определяется как "S".charCodeAt(0)

 

Код клавиши "2/@" определяется как "2".charCodeAt(0)

·                    event.charCode или event.which

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

 

var char = event.keyCode || event.which;

 

Если известен код символа, и по нему нужно получить сам символ, то используют команду вида:

 

String.fromCharCode(char)

·                    event.shiftKey, event.ctrlKey, event.altKey

В событиях keydown, keyup позволяют узнать, были ли дополнительно нажаты специальные клавиши. Проверка данного свойства выполняется аналогично событиям мыши (см. выше).

 

Пример. Пусть при нажатии сочетания клавиш Ctrl + 1 или Ctrl + 2 на странице закрашиваются нечетные или четные абзацы. Так как нужна проверка на нажатие специальных клавиш, то будем писать обработчик для события keydown.

 

<script type="text/javascript">

    //весь код выполняется после загрузки окна

    window.onload = function()

    {

        //получаем массив абзацев

        p = document.getElementsByTagName('p');

        //для всего документа (document.body) задаем обработчик события keydown

        document.body.onkeydown = function()

        {

            //получаем ссылку на параметр event

            var event = event || window.event;

            //если нажаты клавиши Ctrl + 1

            if (event.ctrlKey && event.keyCode=='1'.charCodeAt(0))

                //в цикле проходим по абзацам

                for (var i=0; i<p.length; i++)

                    //нечетные абзацы закрашиваем желтым

                    if (i % 2 == 0)

                        p[i].style.backgroundColor = 'yellow'

                    //четным абзацам возвращаем цвет по умолчанию

                    else

                        p[i].style.backgroundColor = ''

            //если нажаты клавиши Ctrl + 2

            else if (event.ctrlKey && event.keyCode=='2'.charCodeAt(0))

                //в цикле проходим по абзацам

                for (var i=0; i<p.length; i++)

                    //четные абзацы закрашиваем желтым

                    if (i % 2 != 0)

                        p[i].style.backgroundColor = 'yellow'

                    //нечетным абзацам возвращаем цвет по умолчанию

                    else

                        p[i].style.backgroundColor = '';

        }

    }

</script>

 

Пример. Пусть имеется текстовое поле. Написать код, который позволит ввести в поле только цифры.

 

<script type="text/javascript">

    //код выполняется после загрузки окна

    window.onload = function()

    {

        //получаем ссылку на первое поле

        i = document.getElementsByTagName('input')[0];

        //полю присваиваем обработчик события keypress

        i.onkeypress = function()

        {

            //получаем ссылку на параметр event

            var event = event || window.event;

            //получаем код введенного символа

            var char = event.keyCode || event.which;

            //если код символа не попадает в диапазон от 48 до 57

            //в этом диапазоне находятся цифры

            if (char<48 || char >57)

                //отменяем стандартное действие

                //в результате символ не вводится

                return false;

        }

    }

</script>

 

Данный пример требует от разработчика знания кодов символов. Можно переписать пример так, чтобы по коду введенного символа можно получить сам символ, что упрощает написание кода

 

<script type="text/javascript">

    //код выполняется после загрузки окна

    window.onload = function()

    {

        //получаем ссылку на первое поле

        i = document.getElementsByTagName('input')[0];

        //полю присваиваем обработчик события keypress

        i.onkeypress = function()

        {

            //получаем ссылку на параметр event

            var event = event || window.event;

            //получаем код введенного символа

            var char = event.keyCode || event.which;

            //если код символа не попадает в диапазон от 48 до 57

            //в этом диапазоне находятся цифры

            if (String.fromCharCode(char)<'0' || String.fromCharCode(char) >'9')

                //отменяем стандартное действие

                //в результате символ не вводится

                return false;

        }

    }

</script>