jQuery для начинающих. Часть 6. События

Прежде чем приступить к прочтению данной статьи, стоит определиться, что из себя представляют события — для web-странички, событиями будут являться любые действия пользователя – это и ввод данных с клавиатуры, и передвижения мышки, и конечно же “клики” – всё это и есть события. К событиям можно еще отнести события создаваемые скриптами, т.н. триггеры.


Базовые события

Начнем с азов. jQuery работает практически со всеми событиями в JavaScript’е, приведу список функции с небольшими пояснениями:

  • change — измение значения элемента (значение, при потери фокуса, элемента отличается от изначального, при получении фокуса)
  • click — клик по элементу (порядок событий — mousedown, mouseup, click)
  • dblclick — двойной клик по элементу
  • resize — изменение размеров элементов
  • scroll – скроллинг элемента
  • select — выбор текста (актуален только для input[type=text] и textarea)
  • submit — отправка формы
  • focus — фокус на элементе – актуально для input[type=text], но в современных браузерах работает и с другими элементами
  • blur — фокус ушел с элемента – актуально для input[type=text] — срабатывает при клике по другому элементу на странице или по событию клавиатуры (к примеру переключение по tab’у)
  • focusin — фокус на элементе, данное событие срабатывает на предке элемента, для которого произошло событие focus
  • focusout — фокус ушел с элемента, данное событие срабатывает на предке элемента, для которого произошло событие blur
  • keydown — нажатие клавиши на клавиатуре
  • keypress — нажатие клавиши на клавиатуре (порядок событий — keydown, keypress, keyup)
  • keyup — отжатие клавиши на клавиатуре
  • load — загрузка элемента (img)
  • unload — выгрузка элемента (window)
  • mousedown — нажатие клавиши мыши
  • mouseup — отжатие клавиши мыши
  • mousemove — движение курсора
  • mouseenter — наведение курсора на элемент, не срабатывает при переходе фокуса на дочерние элементы
  • mouseleave — вывод курсора из элемента, не срабатывает при переходе фокуса на дочерние элементы
  • mouseover — наведение курсора на элемент
  • mouseout — вывод курсора из элемента

Опробовать события можно на примере с событиями мышки и элементами формы.

Большинство из перечисленных событий можно имитировать непосредственно из самого скрипта:

<script lang="javascript"> $('#menu li').click(); </script>

Триггеры

Для работы с триггерами в jQuery предопределены следующие функции:

  • bind (type, data, fnc) — добавляет обработчик событий
  • one (type, data, fnc) — добавляет обработчик событий, который сработает лишь раз
  • trigger (event, data) — вызывает обработчики событий
  • triggerHandler( event, data) — вызывает обработчики событий, без вызова события браузера
  • unbind (type, fnc) — удаляет все обработчики событий с элемента
$('.class').bind('click', function(){
    // что-то делаем
});

// вызываем обработчик
$('.class').trigger('click');

// отключаем обработчик
$('.class').unbind('click');

Можно повесить триггер почти на любой объект:

var obj = {
    test:function() {
        console.log('obj.test');
    }
}

$(obj).bind('someEvent', function(){
   console.log('obj.someEvent');
   this.test();
});

$(obj).trigger('someEvent');

Пространство имен

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

// создаем свой обработчик
$('.class').bind('click', function(){
    // что-то делаем
});
// удаляем все обработчики
$('.class').unbind();

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

// создаем обработчик
$('.class').bind('click.namespace', function(){
    // что-то делаем
});

// вызываем обработчик
$('.class').trigger('click.namespace');

// удаляем все обработчики в данном пространстве имен
$('.class').unbind('click.namespace');

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

$('.class').bind('click.namespace', function(){
    console.log('bang');
});
$('.class').trigger('click.namespace'); // вызываем событие, наш обработчик сработает
$('.class').trigger('click');           // тоже работает
$('.class').trigger('click.other');     // событие из другого пространства имен, наш обработчик не будет вызван

Так же, есть поддержка нескольких пространств имен (с версии 1.3, если быть точным):

$('.class').bind('click.a.b', function(){
    // для пространств a и b
});
$('.class').trigger('click.a'); // вызываем обработчик из пространства a
$('.class').unbind('click.b');  // отменяем обработчик для пространства b

Можно одним махом удалить все обработчики с определенного пространства имен:

$('.class').bind('click.namespace', function(){}); // обработчик клика
$('.class').bind('blur.namespace', function(){});  // обработчик фокус
$('.class').unbind('.namespace'); // передумали, и все отменили

Работа с live

Очень часто при генерации страниц AJAXом возникает необходимость повесить обработчики событий на новые элементы в DOMе, для этой цели служит метод live (первый параметр — имя события, второй — обработчик).

Приведу пример — есть следующая задача:

  1. все внутренние ссылки на страницы должны подгружать контент AJAXом в элемент с id=content
  2. правило №1 верно для ссылок из подгруженного контента

Реализовать первое требование достаточно просто:

$('a[href^=/]').click(function(event){
    $('#content').load($(this).attr('href'));
    return false; // эквивалентно вызову event.preventDefault(); и event.stopPropagation();
});

Выполнить второе правило тоже легко, достаточно слегка модифицировать предыдущий пример:

$('a[href^=/]').live('click', function(event){
    $('#content').load($(this).attr('href'));
    event.preventDefault(); // отменяем действие по умолчанию, но не трогаем bubbling - чтобы не мешать другим обработчикам
});

Поддерживаемые события: click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, keydown, keypress, keyup, change (1.4), submit (1.4), focusin (1.4), focusout (1.4), mouseenter (1.4), mouseleave (1.4)
Нет поддержки: blur, focus, change, submit

В противовес функции live существует функция die — она убирает отслеживание событий для вновь появившихся элементов.

Touch события

Смартфоны с большим сенсорным экраном — это уже не редкость, вот и web-индустрия начинает адаптироваться под пользователей того же iPhone, если же вам понадобилось подобная адаптация, то вам пригодится следующая информация:

События в JavaScript’е:

  • touchstart &mdash аналогично mousedown
  • touchmove &mdash mousemove
  • touchend &mdash mouseup
  • touchcancel &mdash аналогии нет

О том как с ними работать, можно подчерпнуть из статей iPhone Touch Events in JavaScript и Touching and Gesturing on the iPhone

Если же вернутся к CSS, то для того же iPhone подключение внешнего CSS файла будет выглядеть следующим образом:

<link rel="stylesheet" href="iphone.css" type='text/css' media='only screen and (max-device-width: 480px)' />

Или в самом CSS:

@media only screen and (max-device-width: 480px) {
  .sidebar {
    display: none;
  }
}

Подробнее читайте в статье iPhone Development: 12 Tips To Get You Started (перевод был тут)

Цикл статей

  1. jQuery для начинающих
  2. jQuery для начинающих. Часть 2. JavaScript Меню
  3. jQuery для начинающих. Часть 3. AJAX
  4. jQuery для начинающих. Часть 4. Селекторы
  5. jQuery для начинающих. Часть 5. Эффекты
  6. jQuery для начинающих. Часть 6. События

Другие посты на эту тему

15 Responses to “jQuery для начинающих. Часть 6. События”

  1. deerua says:

    ивенты можно назначать и вызывать непосредственно ихним именем без “on”

    $("#someid").click(function(){
    	$(this).css({});
    }).click();
  2. Разве триггеры это события возбуждаемые скриптом? Насколько мне известно, триггеры – обработчики этих самых событий. Такая терминология в СУБД, и здесь она тоже логику не нарушает. А такой код, мне кажется, следует рассматривать как ручной вызов этого самого обработчика:

    $('.class').trigger('click.namespace');
    
    • С событиями браузера еще понятно – но если брать кастомные события – то такая формулировка вполне подходит, хотя и самому она не очень нравится…

  3. Kein says:

    Подписался на ваш канал в google-reader. Статьи интересные, но вопрос, не могли бы вы их делать под катом, а то уж больно не читабельно когда видна вся статья целиком)

  4. yAnTar says:

    Мені на співбесіді задавали питання, чому live не підтримує подію focus.
    Я не знав реалізації live і не відповів на питання. А live просто вішають на document і потім йде спливання події до потрібного нам елементу. А на документ focus не можна вішати.

  5. vadim says:

    Как вовремя :)
    У меня вопрос – почему обработка scroll события для iframe на Gecko движках обрабатывается, а на WebKit – не?
    Задача – на странице 2 iframe, которые надо синхронно скролить:

    $(document).ready(function(){
        $("#src-frame").contents().scroll(function() {
            $("#tgt-frame").contents().scrollTop($("#src-frame").contents().scrollTop());
        });
        $("#tgt-frame").contents().scroll(function() {
            $("#src-frame").contents().scrollTop($("#tgt-frame").contents().scrollTop());
        });
    });

    В Seamonkey и Firefox все отрабатывае нормально, а в Chrome, Safari и Opera – нет.

  6. Спасибо, за всю серию спасибо

  7. [...] (6-я по счёту) часть цикла статей “jQuery для начинающих” от Антона Шевчука – Событ…. Очень всё подробно и, в то же время, просто написанный [...]

  8. Head says:

    Антон, помогите разобраться с позиционированием

    $(‘.papersize’).change(function () {
    var papersize = $(this).val();
    var id = $(this).attr(“id”);
    if (papersize == ’0′) {
    $(‘div[id]#papertype’).attr(‘disabled’, true);

    По селекту .papersize я либо неверно беру id его div’a либо неверно обращаюсь для вывода. Не силён в Jquery ни разу, всё методом тыка =)

    • arthur says:
      $('div[' + id + ']#papertype')

      Вы просто переменную ставите в кавычки

  9. 1. Используйте кнопки для форматирования кода
    2. Не совсем понятно что происходит в данном коде, но кое-что я бы исправил

    $('#papertype').attr('disabled', disabled');
    
  10. redbook says:

    Таке питання – чи можна емулювати натискання на лінк, а то у мене так не працює

    <a id="a_my" target="_blank" href="http://example.com">example</a>
    $('#a_my').trigger('click')
    або
    $('#a_my').click()
    

    Не спрацьовує жоден з цих варіантів.

  11. redbook says:

    Зробив через

    window.open($('#a_my').attr('href'));

Leave a Reply

Copyright © 2007-2010, Anton Shevchuk. Powered by WordPress