Пользовательские события в jQuery?

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

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

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

Ответ 1

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

(перепечатано на странице с истекшим блогом 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]);
            }
        });
    };
};

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

Триггер и привязка

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

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

$(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
    */
});

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

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

#notifier div, который является частью группы подписчиков .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");
        }
    };
});

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

Ответ 2

Ссылка, содержащаяся в принятом ответе, показывает хороший способ реализовать 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);
});

Ответ 3

Я так думаю.. возможно "привязать" пользовательские события, например (от: 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" ]);
    });

Ответ 4

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

$('#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();
    ...
});

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

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

Ответ 5

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

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

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

и

. Метод 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"] );

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

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

Ответ 6

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

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', ...)

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