2015-05-12 6 views
6

Ich möchte ein translateX mit Übergang auf ein Click-Ereignis animieren, indem Sie eine Klasse zum div in der js hinzufügen. Die Transformations- und Übergangseigenschaften werden in der CSS-Datei hinzugefügt.Übergang funktioniert nicht ohne Abfrage der Eigenschaft 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'; 

Es funktioniert nur, wenn ich die Breite Eigenschaft jedes Element in dem dom abzufragen, bevor die Klasse hinzufügen.

hier ist ein jsfiddle: https://jsfiddle.net/5z9fLsr5/2/

jemand erklären kann, warum dies nicht funktioniert?

+1

Da Sie die "display" -Eigenschaft "zur gleichen Zeit" geändert: https://jsfiddle.net/5z9fLsr5/3/ – Passerby

+0

können Sie Opazität anstelle von Display verwenden: https://jsfiddle.net/5z9fLsr5/4/ – Pete

Antwort

2

Das ist, weil Sie Ihren Übergang beginnen und die display-Eigenschaft "zur gleichen Zeit" geändert haben. Ändern display ruinieren jeden Übergang (Zitat benötigt, zugegebenermaßen), so wäre es eine gute Idee, die display verändern und tatsächlichen Durchfuhr zu isolieren:

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>

Abfragen clientWidth scheint um die Ausführung für einige Zeit zu "pausieren", so funktioniert es auch.

+0

habe nicht erkannt, dass die Display-Propeller meine Animationen so stark beeinflussen. Thx für Ihre schnelle Antwort. Ich dachte auch an eine Art Layout-Triggerung durch Abfragen von Breiten – yacon

+0

@yacon Da 'display' nicht" transitable "ist, wird jeder Übergang mit' display' (selbst wenn Sie 'transition-property' explizit definieren, um ihn auszuschließen) fehlschlagen . – Passerby

0

Das Problem hier ist die Anfangseinstellung von display: none. Für den Layout-Manager des Browsers bedeutet dies, dass das Layout so ausgeführt werden sollte, als wäre das fragliche Element nicht einmal im DOM enthalten (das ist es wohl immer noch). Dies bedeutet, dass der CSS-Stil transform: translateX(-200px); nicht angewendet wird.

dies zu tun:

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

löst beide Modifikationen im Wesentlichen zur gleichen Zeit - das Layout ist nur neu gemacht, nachdem beide Anweisungen ausgeführt wurden. Das Einfügen von document.getElementById('widget2').clientWidth; (clientHeight funktioniert auch) löst den Layout-Manager neu zu streichen und registriert transform: translateX(-200px).

Wie andere vor mir erwähnt haben, ist die Lösung entweder opacity zu verwenden, anstatt display (dies wäre meine Wahl) oder setTimeout mit einer Verzögerung von 0 zu verwenden (siehe Why is setTimeout(fn, 0) sometimes useful?).