2012-11-12 20 views
7

Sto utilizzando il metodo di trigger jQuery per chiamare un evento ... ma si comporta in modo incoerente. A volte chiama l'evento, a volte no.jQuery attiva l'evento personalizzato in modo sincrono?

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

Lo custom-event ha molti ascoltatori aggiunti. È come se il metodo di trigger non fosse sincrono, permettendo di cambiare window.location.href prima di eseguire gli eventi. E quando window.location.href viene modificato, si verifica una navigazione che interrompe tutto.

Come posso attivare gli eventi in modo sincrono?

Uso di jQuery 1.8.1.

Grazie!

EDIT

ho trovato che l'evento, quando viene chiamato ha una traccia dello stack come questo:

  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)

Questo dimostra che jQuery metodo trigger è asincrona. (mi sbagliavo ... questo dimostra che l'evento che stavo chiamando aveva un'animazione al suo interno e chiamava la funzione prevista all'interno del callback dopo l'animazione)

risposta

24

Tu, amico mio, stai cercando jQuery "quando".

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

Per forzare nulla per essere sincrona, si può usare qualcosa di simile ....

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

+1: Sì! Ecco ... grazie! I documenti jQuery 'trigger' non dicono nulla su questo comportamento differito ... anche se è solo un piccolo ritardo, a volte possono causare grossi problemi. –

+6

In realtà ho sbagliato ... 'trigger' è sincrono ... il problema era che c'era un effetto in esecuzione all'interno dell'evento innescato, e il metodo previsto veniva chiamato all'interno del callback. –

+1

Il gestore deve restituire una promessa ;-) –

9

lettura documentazione su triggerHandler:

Invece di restituire l'oggetto jQuery (per consentire il concatenamento), .triggerHandler() restituisce qualsiasi valore restituito dall'ultimo gestore che ha causato l'esecuzione. Se non ci sono gestori di ri attivati, restituisce il valore undefined

Questo punto nella documentazione lasciami pensare che un codice come questo:

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

avrebbe soddisfare le vostre esigenze.

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

+0

Questo è vero ... il problema con il mio codice era ME. =) Non ho visto al momento di postare questa domanda che c'era un effetto UI all'interno dell'evento, e che il codice veniva chiamato solo dal callback di quell'effetto UI, invece di essere chiamato direttamente dal codice di ventilazione. –

+0

È possibile utilizzarlo per attivare il gestore di un evento appartenente a un iFrame separato? In altre parole, posso avere iFrame che comunicano in modo sincrono e impedire che venga elaborato un ulteriore codice finché non viene restituita la risposta? –

+1

@PerryMonschau Sono abbastanza sicuro che javascript non possa comunicare con facilità con iframe. Dai un'occhiata a serviceWorker (https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker) per comunicazioni inter-frame ... oppure manipola l'hash dell'iFrame e guarda l'hash che viene modificato indietro dall'iframe. Oppure, vai per un plugin per il browser ... Ad ogni modo, AFAIK non è una soluzione facile ... – jehon

Problemi correlati