136 votos

Cómo ordenar los eventos vinculados con jQuery

Digamos que tengo una aplicación web que tiene una página, que pueden contener de 4 bloques de secuencia : la secuencia de comandos que escribo puede ser encontrado en uno de esos bloques, pero no sé que uno, que es manejado por el controlador.

Me se unen algunos onclick eventos de un botón, pero me parece que a veces se ejecutan en un orden que yo no esperaba.

Hay una manera de asegurar el orden, o cómo se han manejado este problema en el pasado?

124voto

dowski Puntos 2143

Si el pedido es importante que usted puede crear sus propios eventos y enlazar las devoluciones de llamada de fuego cuando los eventos son provocados por otros devoluciones de llamada.

$('#mydiv').click(function(e) {
    // maniplate #mydiv ...
    $('#mydiv').trigger('mydiv-manipulated');
});

$('#mydiv').bind('mydiv-manipulated', function(e) {
    // do more stuff now that #mydiv has been manipulated
    return;
});

Algo así como que, al menos.

32voto

user563811 Puntos 561

Dowski del método es bueno si todos tus devoluciones de llamada siempre van a estar presentes y que son felices con ellas dependen el uno del otro.

Si desea que las devoluciones de llamada para ser independientes uno de otro, sin embargo, usted podría tomar ventaja de burbujas y adjuntar los acontecimientos posteriores como delegados a los elementos primarios. Los controladores en un padre elementos se activará después de que los controladores en el elemento, continuando hasta el documento. Este es bastante bueno, puede utilizar event.stopPropagation(), event.preventDefault(), etc para saltar y controladores cancelar la onu o de la cancelación de la acción.

$( '#mybutton' ).click( function(e) { 
    // Do stuff first
} );

$( '#mybutton' ).click( function(e) { 
    // Do other stuff first
} );

$( document ).delegate( '#mybutton', 'click', function(e) {
    // Do stuff last
} );

O, si no te gusta esto, usted podría usar a Nick, se Filtra bindLast plugin para forzar un evento para obligarse último: https://github.com/nickyleach/jQuery.bindLast.

O, si usted está usando jQuery 1.5, usted también podría potencialmente hacer algo inteligente con el nuevo Diferida del objeto.

19voto

Ed . Puntos 2160

Yo había estado tratando durante años para generify este tipo de proceso, pero en mi caso yo solo estaba preocupado con el fin de la primera escucha de eventos en la cadena.

Si es de cualquier uso, aquí está mi plugin de jQuery que se une a un detector de eventos que siempre se activa antes que cualquier otra:

** ACTUALIZADO en línea con jQuery cambios (gracias Toskan) **

(function($) {
    $.fn.bindFirst = function(/*String*/ eventType, /*[Object])*/ eventData, /*Function*/ handler) {
        var indexOfDot = eventType.indexOf(".");
        var eventNameSpace = indexOfDot > 0 ? eventType.substring(indexOfDot) : "";

        eventType = indexOfDot > 0 ? eventType.substring(0, indexOfDot) : eventType;
        handler = handler == undefined ? eventData : handler;
        eventData = typeof eventData == "function" ? {} : eventData;

        return this.each(function() {
            var $this = $(this);
            var currentAttrListener = this["on" + eventType];

            if (currentAttrListener) {
                $this.bind(eventType, function(e) {
                    return currentAttrListener(e.originalEvent); 
                });

                this["on" + eventType] = null;
            }

            $this.bind(eventType + eventNameSpace, eventData, handler);

            var allEvents = $this.data("events") || $._data($this[0], "events");
            var typeEvents = allEvents[eventType];
            var newEvent = typeEvents.pop();
            typeEvents.unshift(newEvent);
        });
    };
})(jQuery);

Cosas a tener en cuenta:

  • Esto no ha sido totalmente probado.
  • Se basa en el interior del framework jQuery que no cambia (sólo probado con 1.5.2).
  • No necesariamente activar antes de detectores de eventos que están obligados en cualquier otra forma que como un atributo de la fuente o elemento con jQuery bind() y otras funciones asociadas.

15voto

Adam Bellaire Puntos 42797

El orden de la envolvente de las devoluciones de llamada llamada es gestionada por cada objeto jQuery de datos de eventos. No hay ningún funciones (que yo sepa) que le permiten ver y manipular los datos directamente, sólo puede usar bind() y unbind() (o a cualquiera de los equivalentes de funciones auxiliares).

Dowski del método es el mejor, debe modificar los diferentes obligado devoluciones de llamada para unirse a una secuencia ordenada de eventos personalizados, con la "primera" de devolución de llamada vinculado a la "real" del suceso. De esa manera, no importa en qué orden están obligados, la secuencia se ejecute de la manera correcta.

La única alternativa que veo es algo que realmente, realmente no quiero contemplar: si usted sabe que la unión de la sintaxis de las funciones que puede haber sido obligado antes, el intento de la onu-se unen todas esas funciones y, a continuación, re-unen a ellos en el orden correcto a ti mismo. Que sólo traerá problemas, porque ahora usted tiene código duplicado.

Sería genial si jQuery permite simplemente cambiar el orden de la envolvente de eventos en un objeto de datos de eventos, pero sin necesidad de escribir algo de código para enlazar en el principal jQuery que no parece posible. Y probablemente hay implicaciones de permitir que el que no he pensado, así que tal vez es una omisión deliberada.

6voto

robin Puntos 41
 function bindFirst(owner, event, handler)
 {
  owner.unbind(event, handler);
  owner.bind(event, handler);

  var events = owner.data('events')[event];
  events.unshift(events.pop());

  owner.data('events')[event] = events;
 }

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X