166 votes

Comment ordonner les évènements liés avec jQuery

Disons que j'ai une application web qui a une page qui peut contenir 4 blocs de script le script que j'écris peut être trouvée dans l'un de ces blocs, mais je ne sais pas qui, qui est géré par le contrôleur.

- Je lier certains onclick événements à un bouton, mais je trouve que, parfois, ils s'exécutent dans un ordre, je ne m'attendais pas.

Est-il un moyen d'assurer l'ordre, ou comment avez-vous traité ce problème dans le passé?

136voto

dowski Points 2143

Si l'ordre est important, vous pouvez créer vos propres événements et de lier des rappels à feu lors de ces événements sont déclenchés par d'autres rappels.

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

Quelque chose comme ça au moins.

39voto

user563811 Points 561

Dowski de la méthode est bonne si tous vos rappels sont toujours présents et vous êtes heureux avec eux être dépendants les uns des autres.

Si vous voulez que les rappels à être indépendants les uns des autres, cependant, vous pourrait être pour profiter de bulles et de joindre les événements ultérieurs que les délégués des parents d'éléments. Les gestionnaires sur les éléments de parent sera déclenchée après les gestionnaires sur l'élément, en continuant jusqu'à ce document. C'est assez bonne, que vous pouvez utiliser event.stopPropagation(), event.preventDefault(), etc sauter des gestionnaires et d'annuler ou de l'onu-annuler l'action.

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

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

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

Ou, si vous n'aimez pas cela, vous pouvez utiliser Nick Lessive bindLast plugin à la force d'un événement lié dernier: https://github.com/nickyleach/jQuery.bindLast.

Ou, si vous utilisez jQuery 1.5, vous pouvez aussi être de faire quelque chose d'intelligent avec le nouveau Différé d'objet.

28voto

Ed . Points 2160

J'avais essayé pour les âges à generify de ce type de processus, mais dans mon cas, j'étais le seul souci de l'ordre, de la première écouteur d'événement dans la chaîne.

Si c'est de toute utilisation, voici mon plugin jQuery qui lie un écouteur d'événement qui est toujours déclenché avant toutes les autres:

** Mise à JOUR en ligne avec jQuery changements (merci 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);

Choses à noter:

  • Cela n'a pas été entièrement testé.
  • Il s'appuie sur le fonctionnement interne du framework jQuery ne change pas (testé uniquement avec 1.5.2).
  • Il n'en sera pas nécessairement déclenchée avant que les écouteurs d'événements qui sont liés d'une autre manière que comme un attribut de l'élément source ou à l'aide de jQuery bind() et d'autres fonctions connexes.

15voto

Adam Bellaire Points 42797

L'ordre lié à des rappels sont appelés, est gérée par chaque objet jQuery de données d'événement. Il n'y a pas toutes les fonctions (que je connais) qui vous permettent de visualiser et de manipuler directement les données, vous ne pouvez utiliser bind() et unbind() (ou l'équivalent des fonctions d'assistance).

Dowski de la méthode est la meilleure, vous devez modifier les divers liés rappels à se lier à une séquence ordonnée d'événements personnalisés, avec la "première" de rappel lié à la "vraie" de l'événement. De cette façon, peu importe dans quel ordre ils sont liés, la séquence s'exécute dans le droit chemin.

La seule alternative que je peux voir, c'est quelque chose que vous vraiment, vraiment pas envie de contempler: si vous connaissez la syntaxe de liaison de l'fonctions peuvent avoir été lié, devant vous, essayez de l'onu-lier toutes ces fonctions, et puis re-lier dans le bon ordre vous-même. C'est juste des ennuis, parce que maintenant vous avez le code dupliqué.

Ce serait cool si jQuery vous a permis de vous tout simplement de changer l'ordre des événements liés à un objet de données de l'événement, mais sans écrire un peu de code pour accrocher dans le jQuery de base qui ne semble pas possible. Et il y a probablement des implications de permettre à ce que je n'ai pas pensé, peut-être que c'est une omission intentionnelle.

10voto

Avram Lavinsky Points 422

Veuillez noter que dans le jQuery univers cela doit être mis en œuvre différemment de la version 1.8. La suite de la parution de la note est de jQuery blog:

.de données("événements"): jQuery stocke ses les événements liés à des données dans un objet de données nommé (attendre) événements sur chaque élément. C'est une des données internes structure en 1.8 ce sera supprimée de l'utilisateur des données de l'espace de nom afin de ne pas entrer en conflit avec les éléments de même nom. de jQuery de données d'événement peut encore être accessibles via jQuery._data(élément, "les événements")

Nous avons le contrôle complet de l'ordre dans lequel les gestionnaires d'exécuter dans le jQuery univers. Ricoo des points ci-dessus. Ne ressemble pas à sa réponse lui a valu beaucoup d'amour, mais cette technique est très pratique. Considérons, par exemple, chaque fois que vous devez exécuter votre propre gestionnaire avant un gestionnaire dans une bibliothèque widget, ou vous devez avoir le pouvoir d'annuler l'appel pour le widget gestionnaire du conditionnel:

$("button").click(function(e){
    if(bSomeConditional)
       e.stopImmediatePropagation();//Don't execute the widget's handler
}).each(function () {
    var aClickListeners = $._data(this, "events").click;
    aClickListeners.reverse();
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X