2013-03-04 20 views
5

Sto lavorando a un'applicazione di caricamento di immagini e tutto funziona perfettamente tranne un bug, che si verifica solo in Chrome. Ho ridotto il problema a una richiamata che non sta attraversando.jQuery .fadeOut Callback to .click Not che funziona

Il problema è che un richiamo .fadeOut su un trigger .click() non viene attivato. Ho ricreato una versione semplificata in un violino che è collegato qui sotto. Il primo clic avvia il fadeOut e quando il fadeOut è terminato, il trigger .click non si verifica. Fare clic una seconda volta Fa quindi scattare il grilletto. Tutte le idee perché?

HTML:

<div><input type="file" name="image_file" id="image_file"/></div> 

<div class="overlay_wrap"> 
    Overlast 
</div> 

<a id="click" href="">Click</a> 

jQuery:

$(document).ready(function() { 
    $("#click").click(function(event) { 
     event.preventDefault(); 
     $('.overlay_wrap').fadeOut(1000, function(event){ 
      $('#image_file').trigger('click'); 
     }); 
    }); 
}); 

http://jsfiddle.net/gg2a7/5/

Grazie per l'aiuto!

MODIFICA: il vecchio collegamento Fiddle era cambiato.

+1

In qualche modo posizionare il trigger() nel callback sembra differire l'evento, e sembra che sia la sicurezza di Chrome a fermare l'evento, probabilmente perché pensa che non sia generato dall'utente o qualcosa di simile. Toglierlo dal callback risolve il problema, e il testing con un setTimeout regolare sembra avere lo stesso problema, quindi ha qualcosa a che fare con il differimento del trigger(). C'è una risposta [** qui **] (http://stackoverflow.com/questions/210643/in-javascript-can-i-make-a-click-event-fire-programmatically-for-a-file-input) che tratta di un problema in qualche modo simile. – adeneo

+0

Ecco [un'altra risposta] (http://stackoverflow.com/questions/12134014/how-can-i-programmatically-open-the-file-picker-with-javascript) che supporta ciò che dice adeneo. –

+0

Quindi non c'è modo di aggirare questo? –

risposta

2

Purtroppo, questo non funzionerà. Tutto ha a che fare con le funzioni di timing/threading all'interno dei browser.

Il nocciolo del problema è questo: Il <input type="file" /> può non essere aperto a livello di codice (Loads ofquestions on SO/roba su Google su di esso). Non è solo Chrome; Firefox sta mostrando un messaggio che blocca un pop-up, Safari lo bloccherà, e in IE il modulo non verrà inviato.

La ragione di questo è perché è un potenziale rischio per la sicurezza. Solo un'azione utente può provocare l'apertura di questo <input type="file" />. A causa dello .fadeOut(), il browser non lo riconosce più come un evento utente. Ora torniamo ai tempi/thread dei browser, dal momento che questo funziona come. Non c'è alcuna delega, né un altro thread/timeout di qualche tipo che impedisce l'apertura della finestra di dialogo.

$("#click").click(function(event) { 
    event.preventDefault(); 
    $('#image_file').trigger('click'); 
}); 

JSFiddle.

per mostrare che è in realtà il <input type="file" />, ecco un esempio con <input type="button" /> che fa lavoro:

HTML

<input type="button" name="image_file" id="image_file" value="type='button'" /> 

JS

$("#click").click(function(event) { 
     event.preventDefault(); 
     $('.overlay_wrap').fadeOut(1000, function(){ 
      $('#image_file').trigger('click'); 
     }); 
    }); 

    $('#image_file').click(function() { 
     alert('ok'); 
    }); 

JSFiddle.

Per farla breve: non è possibile farlo con un effetto di dissolvenza. Puoi semplicemente aprire la finestra di dialogo e nascondere l'elemento, ma questo è tutto ciò che c'è da fare.

$("#click").click(function(event) { 
    event.preventDefault(); 
    $('.overlay_wrap').hide(); 
    $('#image_file').trigger('click'); 
}); 

JSFiddle.

+0

Questo è deludente, ma posso aggirarlo. La cosa strana è che quando ho provato su Firefox e IE 10 ha funzionato. FF mi ha dato e "vuoi consentire i popup per questo sito", e IE10 non ha dato alcun avviso, ha funzionato. –

+0

Questo mi stava facendo impazzire. Ero molto confuso perché ha funzionato in un callback di un evento ma non in un callback di un callback di un evento. Sembra che dovrò lavorare su di esso. – Dex

0

Cambia la tua $('.overlay_wrap').fadeOut(1000,complete) a

$('.overlay_wrap').fadeOut(1000); 
complete(); 
+2

Questo non attenderà che la dissolvenza finisca prima di eseguire la funzione completa. –

+0

Hai ragione, mi spiace non ho notato – MIIB