AlexPTS
@AlexPTS
Full stack веб разработчик

Можно ли в jQuery через делегирование отследить событие на объекте?

В jQuery есть метод .on(), который может делегировать событие на передаваемый параметр selector.

Пример того что хочу сделать:
$.fn.pluginName= function () {
   this.each(function () {
       $(document).on('change', this, someHandler);
   });
   return this;
};

$('#someNode').pluginName();


Обработчик someHandler ловит событие change на посторонних элементах, т.к. метод .on() по документации строковый selector ждет, а не объект, хотя ошибок не выкидывает.

Может быть кто-то знает как переопределить или расширить метод, чтобы можно было делегировать событие не с селектора, а с объекта?
  • Вопрос задан
  • 4730 просмотров
Решения вопроса 1
Как вариант:
$.fn.pluginName = function(handler) {

    var self = this;

    $(document)
        .on('change', function(event) {
            if (self.index(event.target) === -1)
                return;
    
            handler(event);
        });

    return this;
};
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
k12th
@k12th
console.log(`You're pulling my leg, right?`);
А каков сакральный смысл отлова события на document в данном случае?

$.fn.pluginName= function () {
   this.each(function () {
       $(this).on('change', someHandler);
   });
   return this;
};


Если вы хотите заюзать делегирование событий из соображений производительности, то и это можно сделать проще:
(function ($) {
    'use strict';

    function someHandler (evt) {
        console.log(evt.target);
    }

    $(function () {
        $(document).on('change', '[data-my-plugin]', someHandler)
    });

    $.fn.myPlugin = function () {
        this.each(function () {
            $(this).attr('data-my-plugin', '')
        });
    }
}(jQuery));

//...

$('#someNode').myPlugin();


Что же до передачи this вторым параметром — то jQuery проверяет, является ли второй параметр строкой, и если нет, то вызов будет равнозначен такому:
$(document).on('change', undefined, this, someHandler);
Ответ написан
Комментировать
AlexPTS
@AlexPTS Автор вопроса
Full stack веб разработчик
А каков сакральный смысл отлова события на document в данном случае?

Да, вы правы, у нас получается по сути тоже самое, что мы просто на объект навесим обработчик по сути.
Хотя если проверить элемент на котором произошло событие не только по селектору, а по набору элементов, то слушатель то у нас один все равно, просто он проверят наличие в некотором множестве. Думаю, что смысл делегирования все равно имеет место быть с точки зрения как производительности, так и работы с динамической моделью DOM.

$(document).on('change', '[data-my-plugin]', someHandler)

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

В вашем примере, я так понимаю, нельзя будет назначить разные обработчики, если мы вызовем свой метод myPlugin() на 2 разных наборах. Чтобы первый вызов один обработчик имел, а второй свой. Тогда для них придется selector уникальный составлять на каждый вызов. Это не гибко.

Возможно есть простой вариант не с использованием jQuery, это не принципиально.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы