Пространства имен событий в jQuery: баг или фича?

  • 3 882
  • Нет комментариев
Пространство имём jQuerry

Стоит сказать, что первым языком программирования, который я увидел в далеком 2006 году, был JavaScript. С тех пор я периодично пытался освоить данный язык, но мои попытки были тщетны. И вот спустя почти 8 лет, на меня снизошло озарение. Суть выше сказанного в том, что я не претендую на звание профи и все, о чем я буду говорить дальше, сугубо мои личные наблюдения и мое субъективное мнение.

При работе с событиями в jQuery добавлен синтаксический сахар, а именно пространства имен.

С первого взгляда штука полезная и возникает вопрос, почему ее нет в нативном JavaScript?

Давайте порассуждаем.

Чем может быть полезно использование пространств имен?

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

$elem.on('click.myplugin', onClickHandler1);
$elem.on('click.myplugin', onClickHandler2);

$elem.off('click.myplugin');

Кто генерирует события?

  • События генерирует браузер в ответ на действия пользователя. Браузер ничего не знает о существовании пространств имен и тем более о jQuery.
  • События генерирует программный код. В jQuery можно генерировать события в указанном пространстве имен.

Заблуждение или правда?

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

Дэвид Флэнаган пишет следующее:

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

Дэвид Флэнаган (David Flanagan) из книги JavaScript. Подробное руководство (JavaScript. The Definitive Guide)

Я решил проверить как обстоят дела на сегодняшний день. Я создал ссылку и флажок.

<a id="link" href="http://google.ru">Go to Google</a>
<input id="checkbox" type="checkbox">

Используя jQuery, сгенерировал события click и focus на этих элементах. Фокус отработал нормально в обоих случаях, флажок отметился, а вот перехода по ссылке не было.

var $link = jQuery('#link'),
    $checkbox = jQuery('#checkbox');

function handler(e) {
    console.log(e);
}

// Событие click

$link.on('click', handler);
$link.trigger('click');     //переход по ссылке не удался

$checkbox.on('click', handler);
$checkbox.trigger('click');

// Событие focus

$link.on('focus', handler);
$link.trigger('focus');

$checkbox.on('focus', handler);
$checkbox.trigger('focus');

Затем я повторил тоже самое, но на нативном JavaScript. В итоге все события отработали на ура. У меня браузер Iceweasel 31.0 (Firefox).

var link = document.getElementById('link'),
    checkbox = document.getElementById('checkbox'),
    event = new MouseEvent('click', {
        clientX: 200,
        clientY: 100
    });

function handler(e) {
    console.log(e);
}

// Событие click

link.addEventListener('click', handler, false);
link.dispatchEvent(event);

checkbox.addEventListener('click', handler, false);
checkbox.dispatchEvent(event);

//если не нужны дополнительные опции, то можно проще
checkbox.click();

// Событие focus

link.addEventListener('focus', handler, false);
link.focus();

checkbox.addEventListener('focus', handler, false);
checkbox.focus();

Зачем генерировать события программно?

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

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

Небольшое отступление. jQuery позволяет обрабатывать события не только на элементах DOM, но и на обычных JavaScript-объектах. Смешение шаблона «Наблюдатель» с событийной моделью DOM вносит путаницу. Я рассматриваю только работу с событиями DOM.

Теперь я задал себе вопрос: «Ты можешь привести реальный пример, когда нужно сгенерировать событие DOM в определенном пространстве имен?».

Я так и не смог найти ответ. Почему при клике на кнопку, должны выполниться «особенные» обработчики? Да и выполниться они смогут только при непосредственном вмешательстве в код и их явной генерации.

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

Выводы

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

Послесловие

Я намеренно не упомянул о нестандартных событиях DOM. Фактически мы можем генерировать любое событие на элементе, какое захотим. И разумеется браузер не сможет сгенерировать его самостоятельно, поэтому придется использовать метод trigger. И возможно для таких событий пространства имен будут полезной фишкой, дабы избежать конфликтов между плагинами. Но и этот факт заставляет меня задать еще как минимум два вопроса.

var $elem = jQuery(document);

function handler(e) {...}

$elem.on('logged.myplugin', handler);

$elem.trigger({
    type: 'logged.myplugin',
    user: 'kyzima-spb',
    pass: '123456789'
});

Тоже самое можно сделать на нативном JavaScript

var event = new CustomEvent('logged.myplugin', {
    'detail': {
        user: 'kyzima-spb',
        pass: '123456789'
    }
});

function handler(e) {...}

document.addEventListener('logged.myplugin', handler, false);

document.dispatchEvent(event);

И я просто оставлю здесь этот текст, с целью послушать ваше мнение:

  • пространства имен для событий нужны или нет?
  • нужна ли программная генерация событий в определенном пространстве имен?
Понравилась статья? Оцени её!
Комментарии (0)
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *