create - Eventos personalizados en jQuery?
jquery events w3schools (6)
Estoy buscando información sobre cómo implementar eventhandling personalizado en jquery de la mejor manera. Sé cómo conectar eventos de los elementos dom como ''clic'', etc., pero estoy construyendo una pequeña biblioteca / complemento javascript para manejar algunas funciones de vista previa.
Tengo un script en ejecución para actualizar un texto en un elemento dom a partir de un conjunto de reglas y datos / entrada del usuario que obtuve, pero ahora necesito el mismo texto que se muestra en otros elementos que este script posiblemente no conozca. Lo que necesito es un buen patrón para observar de algún modo este script produciendo el texto necesario.
Entonces, ¿cómo hago esto? ¿Pasé por alto alguna funcionalidad incorporada en jquery para generar / manejar eventos de usuario o necesito algún plugin de jquery para hacerlo? ¿Cuál crees que es la mejor forma / complemento para manejar esto?
Creo que sí ... es posible "enlazar" eventos personalizados, como (desde: 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" ]);
});
El enlace provisto en la respuesta aceptada muestra una buena manera de implementar el sistema pub / sub utilizando jQuery, pero encontré el código algo difícil de leer, así que aquí está mi versión simplificada del código:
$(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);
});
Es una publicación anterior, pero intentaré actualizarla con una nueva información.
Para usar eventos personalizados, debe vincularlo a algún elemento DOM y activarlo. Entonces necesitas usar
El método .on () toma un tipo de evento y una función de manejo de eventos como argumentos. Opcionalmente, también puede recibir datos relacionados con eventos como su segundo argumento, empujando la función de manejo de eventos al tercer argumento. Todos los datos que se pasen estarán disponibles para la función de manejo de eventos en la propiedad de datos del objeto de evento. La función de manejo de eventos siempre recibe el objeto de evento como su primer argumento.
y
El método .trigger () toma un tipo de evento como su argumento. Opcionalmente, también puede tomar una matriz de valores. Estos valores se pasarán a la función de manejo de eventos como argumentos después del objeto de evento.
El código se ve así:
$(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"] );
Buena explicación se puede encontrar here y here . ¿Por qué exactamente esto puede ser útil? Encontré cómo usarlo en esta excelente explicación del ingeniero de twitter .
PS: en JavaScript simple, puedes hacer esto con el nuevo CustomEvent , pero ten cuidado con los problemas de IE y Safari.
Mira esto:
(reimpreso de la página del blog caducada http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/ según la versión archivada en http://web.archive.org/web/20130120010146/http://jamiethompson.co.uk/web/2008/06/17/publish-subscribe-with-jquery/ )
Publicar / Suscribir con jQuery
17 de junio de 2008
Con el objetivo de escribir una interfaz de usuario jQuery integrada con la funcionalidad fuera de línea de Google Gears, he estado jugando con un poco de código para sondear el estado de la conexión de red usando jQuery.
El objeto de detección de red
La premisa básica es muy simple. Creamos una instancia de un objeto de detección de red que sondeará una URL a intervalos regulares. En caso de que fallasen estas solicitudes HTTP, podemos suponer que se ha perdido la conectividad de la red o que el servidor simplemente no está disponible en este momento.
$.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]);
}
});
};
};
Puede ver la demostración aquí. Configure su navegador para que trabaje fuera de línea y vea qué ocurre .... no, no es muy emocionante
Desencadenar y vincular
Sin embargo, lo que es emocionante (o al menos lo que más me emociona) es el método por el cual el estado se transmite a través de la aplicación. Me he tropezado con un método en gran parte no discutido para implementar un sistema de pub / sub utilizando los métodos trigger y bind de jQuery.
El código de demostración es más obtuso de lo necesario. El objeto de detección de red publica eventos de ''estado'' en el documento que los escucha activamente y, a su vez, publica eventos de ''notificación'' a todos los suscriptores (más sobre ellos más adelante). El razonamiento detrás de esto es que en una aplicación del mundo real probablemente habría más lógica que controle cuándo y cómo se publican los eventos de ''notificación''.
$(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
*/
});
Debido a la aproximación centrada en DOM de jQuery, los eventos se publican (se activan en) elementos DOM. Este puede ser el objeto de ventana o documento para eventos generales o puede generar un objeto jQuery utilizando un selector. El enfoque que he tomado con la demostración es crear un enfoque de casi espacio de nombres para definir suscriptores.
Los elementos DOM que van a ser suscriptores se clasifican simplemente con "suscriptor" y "detección de red". Luego, podemos publicar eventos solo para estos elementos (de los cuales solo hay uno en la demostración) activando un evento de notificación en $(“.subscriber.networkDetection”)
El #notifier
div que es parte del grupo de suscriptores .subscriber.networkDetection
tiene una función anónima vinculada a él, actuando efectivamente como un oyente.
$(''#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");
}
};
});
Ahí vas. Es todo muy detallado y mi ejemplo no es del todo emocionante. Tampoco muestra nada interesante que pueda hacer con estos métodos, pero si alguien está interesado en profundizar en la fuente, siéntase libre. Todo el código está en línea en el encabezado de la página de demostración
Tenía una pregunta similar, pero en realidad estaba buscando una respuesta diferente; Estoy buscando crear un evento personalizado. Por ejemplo, en lugar de decir siempre esto:
$(''#myInput'').keydown(function(ev) {
if (ev.which == 13) {
ev.preventDefault();
// Do some stuff that handles the enter key
}
});
Quiero abreviarlo a esto:
$(''#myInput'').enterKey(function() {
// Do some stuff that handles the enter key
});
desencadenar y enlazar no cuentan toda la historia: este es un plugin de JQuery. http://docs.jquery.com/Plugins/Authoring
La función "enterKey" se adjunta como una propiedad de jQuery.fn: este es el código requerido:
(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/
Una buena parte de lo anterior es que puede manejar la entrada del teclado con gracia en oyentes de enlace como:
$(''a.button'').on(''click enterKey'', function(ev) {
ev.preventDefault();
...
});
Ediciones: se ha actualizado para pasar correctamente this
contexto al controlador y devolver cualquier valor devuelto desde el controlador a jQuery (por ejemplo, en caso de que desee cancelar el evento y el burbujeo). Se actualizó para pasar un objeto de evento de jQuery adecuado a los controladores, incluido el código de clave y la capacidad de cancelar el evento.
Viejo jsfiddle: http://jsfiddle.net/b9chris/VwEb9/24/
Así es como creo eventos personalizados:
var event = jQuery.Event(''customEventName);
$(element).trigger(event);
De acuerdo, podrías simplemente hacer
$(element).trigger(''eventname'');
Pero la forma en que escribí te permite detectar si el usuario ha evitado el incumplimiento o no al hacerlo
var prevented = event.isDefaultPrevented();
Esto le permite escuchar la solicitud de su usuario final de detener el procesamiento de un evento en particular, por ejemplo, si hace clic en un elemento de botón en un formulario, pero no desea que el formulario lo publique si hay un error.
Entonces, por lo general, escucho eventos como ese
$(element).off(''eventname.namespace'').on(''eventname.namespace'', function () {
...
});
Una vez más, podrías hacer
$(element).on(''eventname'', function () {
...
});
Pero siempre me pareció algo inseguro, especialmente si estás trabajando en equipo.
No hay nada malo con lo siguiente:
$(element).on(''eventname'', function () {});
Sin embargo, supongamos que necesito desvincular este evento por el motivo que sea (imagine un botón deshabilitado). Entonces tendría que hacer
$(element).off(''eventname'', function () {});
Esto eliminará todos los eventos de eventname
evento de $(element)
. No puede saber si alguien en el futuro vinculará un evento a ese elemento y también desvinculará inadvertidamente ese evento
La manera segura de evitar esto es ponerle nombre a tus eventos haciendo
$(element).on(''eventname.namespace'', function () {});
Por último, puede haber notado que la primera línea era
$(element).off(''eventname.namespace'').on(''eventname.namespace'', ...)
Personalmente siempre desvincular un evento antes de vincularlo solo para asegurarme de que el mismo controlador de eventos nunca se llame varias veces (imagine que este era el botón de enviar en un formulario de pago y el evento se había vinculado 5 veces)