Пользовательские события в jQuery? - PullRequest
170 голосов
/ 30 декабря 2008

Я ищу информацию о том, как наилучшим образом реализовать пользовательскую обработку событий в jquery. Я знаю, как подключать события из элементов dom, таких как «щелчок» и т. Д., Но я создаю крошечную библиотеку / плагин javascript для обработки некоторых функций предварительного просмотра.

У меня запущен скрипт для обновления некоторого текста в элементе dom из набора правил и ввода данных / данных, полученных мной, но теперь мне нужен тот же текст, показанный в других элементах, которые этот скрипт не может знать из. Мне нужен хороший шаблон, чтобы каким-то образом наблюдать, как этот скрипт производит необходимый текст.

Так как мне это сделать? Я пропустил некоторые встроенные функции в jquery для создания / обработки пользовательских событий или мне нужен какой-нибудь плагин jquery для этого? Какой, по вашему мнению, лучший способ / плагин для этого?

Ответы [ 6 ]

119 голосов
/ 12 февраля 2013

Ссылка, приведенная в принятом ответе, демонстрирует хороший способ реализации pub / sub system с использованием jQuery, но я нашел код несколько сложным для чтения, поэтому вот моя упрощенная версия кода:

http://jsfiddle.net/tFw89/5/

$(document).on('testEvent', function(e, eventInfo) { 
  subscribers = $('.subscribers-testEvent');
  subscribers.trigger('testEventHandler', [eventInfo]);
});

$('#myButton').on('click', function() {
  $(document).trigger('testEvent', [1011]);
});

$('#notifier1').on('testEventHandler', function(e, eventInfo) { 
  alert('(notifier1)The value of eventInfo is: ' + eventInfo);
});

$('#notifier2').on('testEventHandler', function(e, eventInfo) { 
  alert('(notifier2)The value of eventInfo is: ' + eventInfo);
});
102 голосов
/ 30 декабря 2008

Взгляните на это:

(перепечатано со страницы блога с истекшим сроком действия http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/ на основе архивной версии в http://web.archive.org/web/20130120010146/http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/)


Публикация / подписка с помощью jQuery

17 июня 2008 г.

С целью написания пользовательского интерфейса jQuery, интегрированного с автономными функциями Google Gears, я играю с некоторым кодом для опроса состояния сетевого подключения с помощью jQuery.

Объект обнаружения сети

Основная предпосылка очень проста. Мы создаем экземпляр объекта обнаружения сети, который будет регулярно опрашивать URL-адрес. В случае сбоя этих HTTP-запросов мы можем предположить, что сетевое соединение потеряно или сервер просто недоступен в настоящее время.

$.networkDetection = function(url,interval){
    var url = url;
    var interval = interval;
    online = false;
    this.StartPolling = function(){
        this.StopPolling();
        this.timer = setInterval(poll, interval);
    };
    this.StopPolling = function(){
        clearInterval(this.timer);
    };
    this.setPollInterval= function(i) {
        interval = i;
    };
    this.getOnlineStatus = function(){
        return online;
    };
    function poll() {
        $.ajax({
            type: "POST",
            url: url,
            dataType: "text",
            error: function(){
                online = false;
                $(document).trigger('status.networkDetection',[false]);
            },
            success: function(){
                online = true;
                $(document).trigger('status.networkDetection',[true]);
            }
        });
    };
};

Вы можете посмотреть демо здесь. Настройте браузер на работу в автономном режиме и посмотрите, что произойдет ... нет, это не очень интересно.

Запуск и связывание

Что интересно (хотя бы то, что меня волнует), так это метод, с помощью которого статус передается через приложение. Я наткнулся на практически не обсуждаемый метод реализации системы pub / sub с использованием методов триггера и связывания в jQuery.

Демонстрационный код более тупой, чем должен быть. Объект обнаружения сети публикует события «status» в документе, который активно их прослушивает, и, в свою очередь, публикует события «notify» для всех подписчиков (подробнее об этом позже). Причиной этого является то, что в реальном приложении, вероятно, было бы больше логики, управляющей тем, когда и как публикуются события «уведомлять».

$(document).bind("status.networkDetection", function(e, status){
    // subscribers can be namespaced with multiple classes
    subscribers = $('.subscriber.networkDetection');
    // publish notify.networkDetection even to subscribers
    subscribers.trigger("notify.networkDetection", [status])
    /*
    other logic based on network connectivity could go here
    use google gears offline storage etc
    maybe trigger some other events
    */
});

Из-за подхода JQuery, ориентированного на DOM, публикуются (запускаются) элементы DOM. Это может быть объект окна или документа для общих событий или вы можете сгенерировать объект jQuery с помощью селектора. Подход, который я использовал для демонстрации, заключается в создании почти пространственного подхода к определению подписчиков.

Элементы DOM, которые должны быть подписчиками, просто классифицируются как «subscriber» и «networkDetection». Затем мы можем публиковать события только для этих элементов (из которых только один в демоверсии), вызывая событие уведомления на $(“.subscriber.networkDetection”)

Div #notifier, который является частью группы .subscriber.networkDetection подписчиков, затем имеет анонимную функцию, связанную с ним, эффективно выступая в качестве слушателя.

$('#notifier').bind("notify.networkDetection",function(e, online){
    // the following simply demonstrates
    notifier = $(this);
    if(online){
        if (!notifier.hasClass("online")){
            $(this)
                .addClass("online")
                .removeClass("offline")
                .text("ONLINE");
        }
    }else{
        if (!notifier.hasClass("offline")){
            $(this)
                .addClass("offline")
                .removeClass("online")
                .text("OFFLINE");
        }
    };
});

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

20 голосов
/ 30 декабря 2008

Думаю, что так ... возможно связать пользовательские события, например (из: http://docs.jquery.com/Events/bind#typedatafn):

 $("p").bind("myCustomEvent", function(e, myName, myValue){
      $(this).text(myName + ", hi there!");
      $("span").stop().css("opacity", 1)
               .text("myName = " + myName)
               .fadeIn(30).fadeOut(1000);
    });
    $("button").click(function () {
      $("p").trigger("myCustomEvent", [ "John" ]);
    });
15 голосов
/ 16 апреля 2011

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

$('#myInput').keydown(function(ev) {
    if (ev.which == 13) {
        ev.preventDefault();
        // Do some stuff that handles the enter key
    }
});

Я хочу сократить это до:

$('#myInput').enterKey(function() {
    // Do some stuff that handles the enter key
});

триггер и связывание не рассказывают всю историю - это плагин JQuery. http://docs.jquery.com/Plugins/Authoring

Функция "enterKey" присоединяется как свойство к jQuery.fn - это необходимый код:

(function($){
    $('body').on('keydown', 'input', function(ev) {
        if (ev.which == 13) {
            var enterEv = $.extend({}, ev, { type: 'enterKey' });
            return $(ev.target).trigger(enterEv);
        }
    });

    $.fn.enterKey = function(selector, data, fn) {
        return this.on('enterKey', selector, data, fn);
    };
})(jQuery);

http://jsfiddle.net/b9chris/CkvuJ/4/

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

$('a.button').on('click enterKey', function(ev) {
    ev.preventDefault();
    ...
});

Изменения: Обновлено, чтобы правильно передавать правильный контекст this в обработчик и возвращать любое возвращаемое значение из обработчика в jQuery (например, если вы хотели отменить событие и всплывающее окно). Обновлен для передачи корректного объекта события jQuery обработчикам, включая код ключа и возможность отмены события.

Старый jsfiddle: http://jsfiddle.net/b9chris/VwEb9/24/

8 голосов
/ 02 мая 2014

Это старый пост, но я постараюсь обновить его новой информацией.

Чтобы использовать пользовательские события, вам нужно привязать его к некоторому элементу DOM и вызвать его. Так что вам нужно использовать

.on () метод принимает тип события и функцию обработки события как аргументы. При желании он также может получать данные, связанные с событием, как второй аргумент, выдвигающий функцию обработки событий к третьему аргумент. Любые переданные данные будут доступны для события функция обработки в свойстве data объекта события. Событие Функция обработки всегда получает объект события в качестве первого аргумент.

и

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

Код выглядит так:

$(document).on("getMsg", {
    msg: "Hello to everyone",
    time: new Date()
}, function(e, param) {
    console.log( e.data.msg );
    console.log( e.data.time );
    console.log( param );
});

$( document ).trigger("getMsg", [ "Hello guys"] );

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

P.S. В простом javascript вы можете сделать это с новым CustomEvent , но остерегайтесь проблем IE и Safari.

3 голосов
/ 24 мая 2017

Вот как я создаю пользовательские события:

var event = jQuery.Event('customEventName);
$(element).trigger(event);

Конечно, вы могли бы просто сделать

$(element).trigger('eventname');

Но способ, который я написал, позволяет вам определить, помешал ли пользователь по умолчанию или нет, выполнив

var prevented = event.isDefaultPrevented();

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


Затем я обычно слушаю такие события

$(element).off('eventname.namespace').on('eventname.namespace', function () {
    ...
});

Еще раз, вы могли бы просто сделать

$(element).on('eventname', function () {
    ...
});

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

Нет ничего плохого в следующем:

$(element).on('eventname', function () {});

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

$(element).off('eventname', function () {});

Это удалит все eventname события из $(element). Вы не можете знать, будет ли кто-то в будущем также связывать событие с этим элементом, и вы бы случайно отменили привязку и к этому событию

Безопасный способ избежать этого - указать пространство ваших событий, выполнив

$(element).on('eventname.namespace', function () {});

Наконец, вы могли заметить, что первая строка была

$(element).off('eventname.namespace').on('eventname.namespace', ...)

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

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