jQuery в деталях. События.
Доброго времени, друзья!
Вот мы и подошли к обработке событий - одной из важных особенностей jQuery, как впрочем и javascript. Ведь только события являются инициаторами интерактивности и динамичности web-страничек, оживляют пользовательский интерфейс и создают положительную оценку мастерству web-разработчика.
О самих событиях и механизме их работы мы знаем из языка javascript и система событий в jQuery является лишь только дополнением к ним. События в jQuery полностью соответствует W3C стандарту.
Давайте посмотрим и повторим, какие бывают события. Лучше всяких слов, конечно же, будет небольшая визуализация:
Львиная доля событий приходится на действия пользователя через устройства ввода (мышь, клавиатура). Пошевелил курсором мышки или нажал на клавишу? - система тотчас среагирует и вызовет соответствующий обработчик.
jQuery также работает со всеми событиями в javascript, основные из них приведу в таблице:
Событие | Описание |
---|---|
.change() | Устанавливает обработчик изменения заданного элемента формы, либо, запускает это событие. |
.click() | Устанавливает обработчик "клика" мышью по элементу, либо, запускает это событие. |
.blur() | Устанавливает обработчик потери фокуса, либо, запускает это событие. |
.dblclick() | Устанавливает обработчик двойного "клика" мышью по элементу, либо, запускает это событие. |
.focus() | Устанавливает обработчик получения фокуса, либо, запускает это событие. |
.hover() | Устанавливает обработчик(и) двух событий: mouseenter и mouseleave. |
.keydown() | Устанавливает обработчик перехода клавиши клавиатуры в нажатое состояние, либо, запускает это событие. |
.keypress() | Устанавливает обработчик ввода символа с клавиатуры, либо, запускает это событие. |
.keyup() | Устанавливает обработчик возвращения клавиши клавиатуры в ненажатое состояние, либо, запускает это событие. |
.mousedown() | Устанавливает обработчик нажатия кнопки мыши на элементе, либо, запускает это событие. |
.mouseenter() | Устанавливает обработчик появления курсора над элементом, либо, запускает это событие. |
.mouseleave() | Устанавливает обработчик выхода курсора из области элемента, либо, запускает это событие. |
.mousemove() | Устанавливает обработчик движения курсора мыши внутри элемента, либо, запускает это событие. |
.mouseout() | Устанавливает обработчик выхода курсора из области элемента, либо, запускает это событие. |
.scroll() | Устанавливает обработчик "прокрутки" элементов документа, либо, запускает это событие. |
.resize() | Устанавливает обработчик изменения размеров окна браузера, либо, запускает это событие. |
Как видно из описания, каждый метод может быть как обработчиком, так и инициатором события. То есть, говоря простыми словами, мы просто можем эмулировать клик мышкой по определенному элементу, либо практически любое другое действие пользователя.
Прежде чем перейти к практике, позвольте рассказать про обработчики событий. Ведь без них от самих событий не будет никакого толку.
Обработчик событий — это метод, связанный с событием. При возникновении события выполняется код внутри обработчика событий.
Распространенная практика в javascript использовать в качестве обработчика событий анонимную функцию. Выглядит это примерно так:
$('#submit').click(function(event){
alert('Форма отправлена!');
});
То есть при нажатии на элемент с ID равным submit происходит вызов анонимной функции function(event){}
а в ней уже запускается alert
с текстом.
А теперь давайте посмотрим как отрабатывают некоторые базовые события, например click
, описание в комментариях к jQuery коду.
HTML:
<body style="position: relative">
<img src="https://s6.postimg.org/srsafs29d/ptica.jpg" id="bird">
<img src="https://s6.postimg.org/5cadafii9/enot.jpg" id="enot">
<img src="https://s6.postimg.org/5rln3g4fl/troll.png" id="troll">
</body>
jQuery код:
$(function(){
// при клике на картинку с ID = #bird выдается alert
$('#bird').click(function(){
alert('Вы нажали на птицу');
});
// при клике на картинку с ID = #enot выдается alert
$('#enot').click(function(){
alert('Вы нажали на енота');
});
// при клике по картинке ID = #troll вызвать предыдущие 2 события
$('#troll').click(function(){
$('#enot').click();
// можно также навесить событие через метод trigger
$('#bird').trigger('click');
});
});
Результат:
Протестируем .mousemove
, описание в комментариях к jQuery коду:
HTML
<style>
img:not(#fly){
margin: 20px;
}
#fly{
position: absolute;
width: 30px;
}
</style>
<body style="position: relative">
<img src="https://s6.postimg.org/srsafs29d/ptica.jpg" id="bird">
<img src="https://s6.postimg.org/5cadafii9/enot.jpg" id="enot">
<img src="https://s6.postimg.org/5rln3g4fl/troll.png" id="troll">
<img src="https://s6.postimg.org/srsafs29d/ptica.jpg" id="fly">
</body>
jQuery код:
$(function(){
var fly_object = $('#fly');
// при каждом движении курсора мыши переопределяем координаты изображения #fly
$(window).mousemove(function(event){
fly_object.css('left',event.pageX+'px');
fly_object.css('top', event.pageY+'px');
});
// при клике на картинку заменим источник картинки на ту, по которой кликнули.
$('img').click(function(){
fly_object.attr('src', $(this).attr('src'));
});
});
Результат:
Заглянем под капот.
Все функции событий, приведенные в таблице (а также не упомянутые в ней) являются по своей сути оболочкой для следующей конструкции по вызову обработчика:
if(arguments.length > 0){
// здесь навешивается обработчик click, в случае, если в функцию .click(params) передали параметры - например анонимную функцию - обработчик.
this.on('click', null, data, fn);
} else {
// а здесь происходит эмуляция события click, когда в .click() ничего не передали
this.trigger('click');
}
Почти во всех случаях следует использовать методы-обертки - это здорово экономит время при написании кода, а также улучшает читабельность кода.
Всплытие и перехват
Когда говорим о событиях, нельзя не упомянуть об одном интересном поведении как всплытие.
Например, есть код формы:
<form>
<div>
<input type='text' name="fio" id="fio" placeholder='Введите ваше имя'/>
</div>
<div>
<textarea></textarea>
</div>
<div>
<input type='submit' value='Отправить'>
</div>
</form>
код jQuery:
$(function(){
$('form').click(function(){
alert('Обработчик для form');
});
$('#fio').click(function(){
alert('Обработчик для поля fio');
});
});
В результате мы видим, что при нажатии любого дочернего элемента формы, будет вызываться обработчик для самой формы. И так в случае с любыми вложенными элементами.
Этот процесс называется всплытием, потому что события «всплывают» от внутреннего элемента вверх через родителей, подобно тому, как всплывает пузырек воздуха в воде.
То есть наступлении события обработчики сначала срабатывают на самом вложенном элементе, затем на его родителе, затем выше и так далее, вверх по цепочке вложенности.
А как же узнать, какой элемент был первым в цепочке событий?
Где бы мы ни поймали событие, всегда можно узнать, где конкретно оно произошло.
Самый глубокий элемент, который вызывает событие, называется «целевым» или «исходным» элементом и доступен как event.target.
Например, вызвав в предыдущем примере e.target
:
$('form').click(function(e){
console.log(e.target);
alert('Обработчик для form');
});
Нам вернется самый первый элемент, по которому кликнул пользователь.
Как прекратить это всплытие?
Очень часто приходится обрывать цепочку всплытий, после того, как был обработано событие на интересующий элемент.
Для этого необходимо вызвать: event.stopPropagation()
Если у элемента есть несколько обработчиков на одно событие, то даже при прекращении всплытия все они будут выполнены.
То есть, event.stopPropagation()
препятствует продвижению события дальше, но на текущем элементе все обработчики отработают.
Для того, чтобы полностью остановить обработку, необходимо пользоваться методом event.stopImmediatePropagation()
. Он не только предотвращает всплытие, но и останавливает обработку событий на текущем элементе.
В нашем предыдущем примере это будет выглядеть так:
$('form').click(function(e){
/* здесь выполняем
* необходимые действия
* с целевым элементом e.target
*/
// прекращаем всплытие к родителям
e.stopPropagation();
alert('Обработчик для form');
});
В результате мы обработаем событие для полей ввода, а до самой формы очередь не дойдет и alert
не вызовется.
Пространства имен.
В jQuery поддерживается пространства имен - эта не часто применяемая, но очень полезная возможность используется, когда возникает необходимость максимально отделить код отдельного участка программы от общего кода, например при создании плагинов.
Для этого всего лишь необходимо указать после типа события через точку .
любое название латинскими буквами - это и будет пространством имен.
Например: on('click.name', handler)
где name
- пространство имен, а click
- тип события
Чтобы понять, как это работает, давайте посмотрим пример:
HTML:
<div>
<input type="button" value="Морские обитатели" id="sea_show"/>
<input type="button" value="Сухопутные животные" id="tierra_show"/>
</div>
<img src="https://s6.postimg.org/cynbzbfch/monk.png" class="tierra">
<img src="https://s6.postimg.org/5cadafii9/enot.jpg" class="tierra">
<img src="https://s6.postimg.org/qr1quy641/eleph.png" class="tierra">
<img src="https://s6.postimg.org/7oid80v3l/whale.png" class="sea">
<img src="https://s6.postimg.org/ix159jyb5/dolph.png" class="sea">
<img src="https://s6.postimg.org/58gju6d0x/shark.png" class="sea">
jQuery код:
$(function(){
// навешиваем обработчик на кнопку показа морских обитателей
$('#sea_show').click(function(){
// вызываем событие показа для пространства имен 'sea'
$('div').trigger('show.sea');
});
// обработчик события для пространства имен 'sea'
$('div').on('show.sea', function(){
$('.sea').show();
$('.tierra').hide();
});
// навешиваем обработчик на кнопку показа сухопутных животных
$('#tierra_show').click(function(){
// вызываем событие показа для пространства имен 'tierra'
$('div').trigger('show.tierra');
});
// обработчик события для пространства имен 'tierra'
$('div').on('show.tierra', function(){
$('.tierra').show();
$('.sea').hide();
});
});
С первого взгляда видно, что код избыточен и можно было обойтись без пространств имен, поместив всю логику в обработчик click
для каждой кнопки. Но данный пример "на пальцах" показывает принцип работы с пространствами имен.
Получим такой результат:
Вот и все на сегодня! Надеюсь, что урок был не сложным для вас и вы разобрались с принципами работы событий в jQuery.
До следующих встреч.
Содержание прошлых уроков:
Вступление
Селекторы и поиск элементов
Фильтры
Оптимизация поиска
Манипуляции с CSS, атрибутами и классами
Всегда рад Вашему вниманию, голосуйте и комментируйте.
Подписывайтесь, дальше здесь будет очень интересно.