last - jquery prev
¿Evento personalizado en jQuery que no está vinculado a un elemento DOM? (7)
La vinculación a elementos no dom ha sido eliminada en jQuery 1.4.4.
Tengo curiosidad si es posible crear un evento personalizado en jQuery que no esté vinculado a un elemento DOM.
Realmente prefiero jQuery a YUI, pero hay una cosa en YUI que me gusta, que es crear eventos personalizados y poder suscribirlos más tarde.
Por ejemplo, esto crea un evento que está vinculado a una variable, no a un elemento DOM:
var myevent = new YAHOO.util.CustomEvent("mycustomevent");
Todos los ejemplos y documentación que he estado leyendo para jQuery requieren algo como:
$(''body'').bind(''mycustomevent'', function(){
//do stuff
});
Para los lectores futuros, es bastante simple hacer esto. Investigué más después de publicar mi pregunta. Desafortunadamente ninguno de los otros comentaristas estaba en lo correcto.
Para enlazar un evento personalizado:
$().bind(''mycustomevent'', function(){
//code here
});
Además, puede generar datos en el objeto de evento que se puede acceder más tarde:
$({mydata:''testdata''}).bind(''mycustomevent'',function(){
//code here
});
Puede desencadenar eventos globales personalizados como este en jQuery:
jQuery.event.trigger(''mycustomevent'', [arg1, arg2, arg3]);
Estos activarán cualquier elemento.
Dado que jQuery se basa en objetos DOM, debe vincular sus eventos a objetos DOM. Probablemente también pueda encontrar la manera de enlazar eventos sin un elemento (lo hizo), pero esa no es una metodología admitida.
Como escribió en su propia respuesta, puede vincular su evento a un objeto DOM global si no desea vincularlo a un elemento de página individual:
$(document).bind(''mycustomevent'', function (e, arg1, arg2, arg3) { /* ... */ });
Según un comentario de John Resig , se admiten eventos vinculantes a objetos personalizados a través de jQuery:
No hay una razón en particular por la que no esté documentado (aparte de que es bastante no tradicional para la mayoría de los usuarios), pero sí, lo apoyamos y tenemos pruebas unitarias para ello.
Entonces esto funciona:
var a = {foo: ''bar''};
$(a).on(''baz'', function() {console.log(''hello'')});
$(a).triggerHandler(''baz'');
>>> ''hello''
La mayoría de los usuarios necesitarán triggerHandler()
, no trigger()
. Si se .trigger("eventName")
, buscará una propiedad "eventName" en el objeto e intentará ejecutarlo después de que se ejecuten los manejadores de jQuery conectados ( bugs.jquery.com/ticket/7818#comment:26 ).
EDITAR (28.02.2017):
Después de usar este patrón durante aproximadamente 2 años en una gran base de código, puedo dar fe de que esta es una mala idea. Estos eventos personalizados generan flujos de datos incomprensibles. Prefiere devoluciones de llamada en su lugar
Todavía puede activar y responder de forma arbitraria a eventos usando jQuery, incluso si no sabe a qué elemento adjuntarlos. Simplemente crea un elemento "receptor" en tu documento, al que puedes vincular todos tus eventos personalizados. Esto le permite administrar su lógica de manejo de eventos en un solo lugar, para todos sus eventos no específicos de elementos.
$(document).ready(function() {
$(body).append(''<div id="receiver">'');
$("#receiver").bind("foo_event", function () {
// decide what to do now that foo_event has been triggered.
});
$("#some_element").click(function() {
$("#receiver").trigger("foo_event");
});
});
[EDITAR]
Aquí hay una clase trabajadora que usa los conceptos escritos a continuación:
https://github.com/stratboy/image-preloader
Es solo un preloader de imagen secuencial. Puede suscribirse a un montón de eventos. Echar un vistazo.
[/EDITAR]
Publicación antigua:
Aquí hay otro ejemplo de barebones con devoluciones de llamada como lo sugiere Himanshu P.
Estoy construyendo una clase y vengo de Mootools, donde cosas como Clases y eventos personalizados implementados directamente en clases (por lo tanto, no vinculados a elementos DOM) son absolutamente naturales. Así que probé una especie de solución y comparto a continuación.
var step_slider;
//sandbox
;(function($) {
//constructor
var StepSlider = function(slider_mask_selector,options) {
//this.onStep = $.Event(''step'');
this.options = null;
this.onstep = $.Callbacks();
this.init();
}//end constructor
StepSlider.prototype = {
init:function(){
this.set_events();
},//end init
set_events:function(){
if(this.options){
if(this.options.onstep){
this.subscribe(''step'',options.onstep);
}
}
},//set_events
subscribe:function(event,action){
this[''on''+event].add(action);
},
fire_onstep:function(){
this.onstep.fire({ data1:''ok'' });
}
}//end prototype/class
//--------------------
$(document).ready(function() {
step_slider = new StepSlider(''selector'');
//for example, say that you have a div#next-button, you can then do this:
$(''#next-button'').click(function(){
step_slider.fire_onstep();
});
});//end domready
})(jQuery);
jQuery Callbacks proporciona una forma simple de implementar un sistema pub-sub independiente del DOM.
Cerca de la parte inferior de la página vinculada está el código de ejemplo que muestra cómo hacerlo.