2012-11-12 7 views
7

Ich verwende die jQuery-Trigger-Methode, um ein Ereignis aufzurufen ... aber es verhält sich inkonsistent. Manchmal ruft es das Ereignis auf, manchmal nicht.jQuery benutzerdefinierte Ereignisse synchron auslösen?

<a href="#" onclick=" 
    $(this).trigger('custom-event'); 
    window.location.href = 'url'; 
    return false; 
">text</a> 

Die hat viele Zuhörer hinzugefügt. Es ist, als wäre die Trigger-Methode nicht synchron, so dass die window.location.href vor der Ausführung der Ereignisse geändert werden kann. Und wenn window.location.href geändert wird, findet eine Navigation statt, die alles unterbricht.

Wie kann ich Ereignisse synchron auslösen?

Verwenden von jQuery 1.8.1.

Danke!

EDIT

ich gefunden habe, dass das Ereignis, wenn hat einen Stack-Trace wie folgt aufgerufen:

  1. jQuery.fx.tick (jquery-1.8.1.js: 9021)
  2. tick (jquery-1.8.1.js: 8499)
  3. jQuery.Callbacks.self.fireWith (jquery-1.8.1.js: 1082)
  4. jQuery.Callbacks.fire (jquery-1.8.1. js: 974)
  5. jQuery.speed.opt.complete (jquery-1.8.1.js: 8991)
  6. $ .customEvent (myfile.js: 28)

Dies beweist, dass jQuery trigger Verfahren asynchron ist. (Ich habe mich geirrt ... das beweist nur, dass das Ereignis, das ich anrief, eine Animation enthielt und die erwartete Funktion innerhalb des Callbacks nach der Animation aufruft)

Antwort

24

Sie, mein Freund, suchen nach jQuery "wann".

http://api.jquery.com/jQuery.when/

Um alles synchron zu sein zu zwingen, können Sie so etwas wie dieses verwenden ....

$.when($(this).trigger('custom-event')).done(function(){ 
    window.location.href = 'url'; 
}); 
+0

+1: Ja! Das ist es ... danke! jQuery 'trigger'-Dokumente sagen nichts über dieses verzögerte Verhalten ... selbst wenn es nur eine kleine Verzögerung ist, kann es manchmal zu großen Problemen kommen. –

+6

Tatsächlich lag ich falsch ... 'trigger' ist synchron ... Das Problem war, dass ein Effekt innerhalb des ausgelösten Ereignisses lief und die erwartete Methode innerhalb des Callbacks aufgerufen wurde. –

+1

Der Handler muss ein Versprechen abgeben ;-) –

9

Dokumentation über triggerHandler Lesen:

Anstatt das jQuery-Objekt zurückzugeben (um die Verkettung zu ermöglichen), gibt triggerHandler() den Wert zurück, der vom letzten Handler zurückgegeben wurde, für den die Ausführung ausgeführt wurde. Wenn keine Handler ausgelöst sind, gibt es nicht definiert

Dieser Punkt in der Dokumentation lassen mich denken, dass ein Code wie folgt aus:

// Trigger the custom event 
$(this).triggerHandler('custom-event'); 
// This code will only run when all events are run 
window.location.href = 'url'; 

würde Ihre Anforderungen erfüllen.

Siehe http://api.jquery.com/triggerHandler/

+0

Das ist wahr ... das Problem mit meinem Code war ME. =) Ich habe im Moment des Stellens dieser Frage nicht gesehen, dass es einen UI-Effekt innerhalb des Ereignisses gab, und dass der Code nur vom Callback dieses UI-Effekts aufgerufen wurde, anstatt direkt vom Vent-Code angerufen zu werden. –

+0

Können Sie damit den Handler eines Ereignisses, das zu einem separaten iFrame gehört, auslösen? Mit anderen Worten: Kann ich iFrames synchron kommunizieren lassen und verhindern, dass weiterer Code verarbeitet wird, bis die Antwort zurückgegeben wurde? –

+1

@PerryMonschau Ich bin mir ziemlich sicher, dass JavaScript nicht so einfach mit iframe kommunizieren kann. Werfen Sie einen Blick auf serviceWorker (https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker) für Inter-Frame-Kommunikation ... Oder manipulieren Sie den Hash-Wert des iFrame und sehen Sie sich an, wie der Hash-Wert geändert wird aus dem iframe. Oder, gehen Sie für ein Browser-Plugin ... Wie auch immer, AFAIK keine einfache Lösung ... – jehon