Nehmen wir an, ich habe eine Web-App mit einer Seite, die 4 Skriptblöcke enthalten kann. Das Skript, das ich schreibe, befindet sich möglicherweise in einem dieser Blöcke, aber ich weiß nicht, welches vom Controller verarbeitet wird.
Ich binde einige onclick
Ereignisse an eine Schaltfläche, stelle jedoch fest, dass sie manchmal in einer Reihenfolge ausgeführt werden, die ich nicht erwartet hatte.
Gibt es eine Möglichkeit, die Ordnung sicherzustellen, oder wie haben Sie dieses Problem in der Vergangenheit behandelt?
javascript
jquery
events
mkoryak
quelle
quelle
Antworten:
Ich hatte lange versucht, diese Art von Prozess zu verallgemeinern, aber in meinem Fall ging es mir nur um die Reihenfolge des ersten Ereignis-Listeners in der Kette.
Wenn es von Nutzen ist, ist hier mein jQuery-Plugin, das einen Ereignis-Listener bindet, der immer vor allen anderen ausgelöst wird:
** AKTUALISIERT im Einklang mit jQuery-Änderungen (danke Toskan) **
Dinge zu beachten:
quelle
this.data("events")
, siehe hier stackoverflow.com/questions/12214654/…Wenn die Reihenfolge wichtig ist, können Sie Ihre eigenen Ereignisse erstellen und Rückrufe an das Feuer binden, wenn diese Ereignisse durch andere Rückrufe ausgelöst werden.
Zumindest so etwas.
quelle
Dowskis Methode ist gut, wenn alle Ihre Rückrufe immer vorhanden sind und Sie zufrieden sind, dass sie voneinander abhängig sind.
Wenn Sie jedoch möchten, dass die Rückrufe unabhängig voneinander sind, können Sie das Sprudeln nutzen und nachfolgende Ereignisse als Delegaten an übergeordnete Elemente anhängen. Die Handler für übergeordnete Elemente werden nach den Handlern für das Element ausgelöst und bis zum Dokument fortgesetzt. Das ist ziemlich gut , wie Sie verwenden können
event.stopPropagation()
,event.preventDefault()
etc Handler zu überspringen und stornieren oder un-brechen Sie die Aktion.Wenn Ihnen das nicht gefällt, können Sie das bindLast-Plugin von Nick Leaches verwenden, um zu erzwingen, dass ein Ereignis zuletzt gebunden wird: https://github.com/nickyleach/jQuery.bindLast .
Wenn Sie jQuery 1.5 verwenden, können Sie mit dem neuen Objekt "Zurückgestellt" möglicherweise auch etwas Kluges tun.
quelle
.delegate
wird nicht mehr verwendet und Sie sollten jetzt verwenden.on
, aber ich weiß nicht, wie Sie das gleiche Verhalten miton
Die Reihenfolge, in der die gebundenen Rückrufe aufgerufen werden, wird von den Ereignisdaten jedes jQuery-Objekts verwaltet. Es gibt keine Funktionen (die mir bekannt sind), mit denen Sie diese Daten direkt anzeigen und bearbeiten können. Sie können nur bind () und unbind () (oder eine der entsprechenden Hilfsfunktionen) verwenden.
Dowskis Methode ist am besten, Sie sollten die verschiedenen gebundenen Rückrufe so ändern, dass sie an eine geordnete Folge von benutzerdefinierten Ereignissen gebunden sind, wobei der "erste" Rückruf an das "echte" Ereignis gebunden ist. Auf diese Weise wird die Sequenz unabhängig von der Reihenfolge, in der sie gebunden sind, auf die richtige Weise ausgeführt.
Die einzige Alternative, die ich sehen kann, ist etwas, über das Sie wirklich, wirklich nicht nachdenken möchten: Wenn Sie wissen, dass die Bindungssyntax der Funktionen möglicherweise vor Ihnen gebunden wurde, versuchen Sie, alle diese Funktionen zu lösen und sie dann erneut zu binden in der richtigen Reihenfolge. Das ist nur ein Problem, denn jetzt haben Sie Code dupliziert.
Es wäre cool, wenn Sie mit jQuery einfach die Reihenfolge der gebundenen Ereignisse in den Ereignisdaten eines Objekts ändern könnten, ohne jedoch Code zum Einbinden in den jQuery-Kern zu schreiben, der nicht möglich erscheint. Und es gibt wahrscheinlich Implikationen, dies zuzulassen, an die ich nicht gedacht habe. Vielleicht ist es eine absichtliche Auslassung.
quelle
Bitte beachten Sie, dass dies im jQuery-Universum ab Version 1.8 anders implementiert werden muss. Der folgende Versionshinweis stammt aus dem jQuery-Blog:
Wir haben die vollständige Kontrolle über die Reihenfolge, in der die Handler im jQuery-Universum ausgeführt werden . Ricoo weist oben darauf hin. Sieht nicht so aus, als hätte ihm seine Antwort viel Liebe eingebracht, aber diese Technik ist sehr praktisch. Betrachten Sie beispielsweise jedes Mal, wenn Sie Ihren eigenen Handler vor einem Handler in einem Bibliotheks-Widget ausführen müssen, oder wenn Sie die Möglichkeit haben müssen, den Aufruf des Handlers des Widgets unter bestimmten Bedingungen abzubrechen:
quelle
Binden Sie den Handler einfach normal und führen Sie dann Folgendes aus:
so zum Beispiel:
quelle
$._data(element, 'events')[name].reverse()
funktioniertquelle
Sie können so etwas ausprobieren:
quelle
Ich habe das gleiche Problem und habe dieses Thema gefunden. Die obigen Antworten können dieses Problem lösen, aber ich denke nicht, dass sie gute Pläne sind.
Lassen Sie uns über die reale Welt nachdenken.
Wenn wir diese Antworten verwenden, müssen wir unseren Code ändern. Sie müssen Ihren Codestil ändern. etwas wie das:
Original:
hacken:
Denken Sie im Laufe der Zeit an Ihr Projekt. Der Code ist hässlich und schwer zu lesen! Anthoer Grund ist einfach ist immer besser. Wenn Sie 10 bindAtTheStart haben, kann es keine Fehler geben. Wenn Sie 100 bindAtTheStart haben, sind Sie wirklich sicher, dass Sie sie in der richtigen Reihenfolge halten können?
Wenn Sie also dieselben Ereignisse mehrfach binden müssen. Ich denke, der beste Weg ist, die Ladereihenfolge für js-Datei oder js-Code zu steuern. jquery kann Ereignisdaten als Warteschlange verarbeiten. Die Reihenfolge ist First-In, First-Out. Sie müssen keinen Code ändern. Ändern Sie einfach die Ladereihenfolge.
quelle
Hier ist meine Aufnahme, die verschiedene Versionen von jQuery abdeckt:
quelle
In einigen besonderen Fällen, in denen Sie die Bindung der Klickereignisse nicht ändern können (Ereignisbindungen werden aus den Codes anderer erstellt) und das HTML-Element ändern können, ist hier eine mögliche Lösung ( Warnung : Dies ist nicht die empfohlene Methode zum Binden Ereignisse, andere Entwickler können Sie dafür ermorden):
Bei dieser Art der Bindung wird Ihr Event-Hander zuerst hinzugefügt, sodass er zuerst ausgeführt wird.
quelle
JQuery 1.5 führt Versprechen ein, und hier ist die einfachste Implementierung, die ich gesehen habe, um die Ausführungsreihenfolge zu steuern. Vollständige Dokumentation unter http://api.jquery.com/jquery.when/
quelle