Пользовательские события в 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 раз)