2015-05-12 10 views
6

Desidero animare un traduttoreX con la transizione su un evento click aggiungendo una classe al div in js. Le proprietà di trasformazione e transizione vengono aggiunte nel file css.Transizione non funziona senza interrogare la proprietà width

var widget = document.getElementById('widget');  
widget.style.display = 'block'; 
document.getElementById('widget2').clientWidth; //comment this line out and it wont work 
widget.className = 'visible'; 

funziona solo se interrogo la proprietà width di qualsiasi elemento del DOM prima di aggiungere la classe.

ecco un jsfiddle: https://jsfiddle.net/5z9fLsr5/2/

qualcuno può spiegare il motivo per cui questo non sta funzionando?

+1

Perché hai modificato la proprietà 'display' allo stesso tempo": https://jsfiddle.net/5z9fLsr5/3/ – Passerby

+0

potresti usare l'opacità invece del display: https://jsfiddle.net/5z9fLsr5/4/ – Pete

risposta

2

Questo è perché si inizia la transizione e si modifica la proprietà display "allo stesso tempo". Alterare display sarà rovinare qualsiasi transizione (citazione necessaria, è vero), quindi sarebbe una buona idea per isolare il display cambia e il transito effettivo:

https://jsfiddle.net/5z9fLsr5/3/

document.getElementById('showWidget').addEventListener('click', function(e) { 
 
    e.preventDefault(); 
 
    var widget = document.getElementById('widget');  
 
    widget.style.display = 'block'; 
 
    //document.getElementById('widget2').clientWidth; 
 
    window.setTimeout(function(){ 
 
     widget.className = 'visible'; 
 
    },0); 
 
});
#widget { 
 
    width: 200px; 
 
    height: 80px; 
 
    background: black; 
 
    position: absolute; 
 
    transition: transform 500ms; 
 
    transform: translateX(-200px); 
 
    display: none; 
 
} 
 
#widget.visible { 
 
    transform: translateX(200px); 
 
} 
 

 

 

 
#widget2 { 
 
    position: absolute; 
 
    right: 0 
 
}
<a href="#" id="showWidget">show</a> 
 
<div id="widget"></div> 
 
<div id="widget2">xxx</div>

Interrogazione clientWidth sembra per "mettere in pausa" l'esecuzione per un po 'di tempo, quindi funziona anche.

+0

non si è reso conto che l'oggetto di visualizzazione ha un tale impatto sulle mie animazioni. Thx per la tua rapida risposta. Ho anche pensato ad una sorta di trigger di layout interrogando le larghezze – yacon

+0

@yacon Perché 'display' non è" transitable ", quindi qualsiasi transizione che coinvolge' display' (anche se si definisce esplicitamente 'transition-property' per escluderla) fallirà . – Passerby

0

Il problema qui è l'impostazione iniziale di display: none. Per il gestore del layout del browser, questo indica che il layout dovrebbe essere eseguito come se l'elemento in questione non fosse nemmeno nel DOM (lo è ancora, attenzione). Ciò significa che lo stile CSS transform: translateX(-200px); non verrà applicato.

Fare questo:

widget.style.display = 'block'; 
widget.className = 'visible'; 

innesca due modifiche sostanzialmente allo stesso tempo - la disposizione è ri-fatto solo dopo che sono state eseguite entrambe le istruzioni. L'inserimento di document.getElementById('widget2').clientWidth; (clientHeight funziona inoltre) fa in modo che il gestore di layout ridisegni, registrando così transform: translateX(-200px).

Come altri hanno detto prima di me, la soluzione è usare sia per opacity invece di display (questa sarebbe la mia scelta), o per utilizzare setTimeout con un ritardo di 0 (vedi Why is setTimeout(fn, 0) sometimes useful?).

Problemi correlati