2014-02-09 2 views
18

Ich entwickle Non-jQuery-responsive Image-Slider basierend auf CSS3-Übergängen.Browser erzwingen, Reflow beim Ändern von CSS auszulösen

Die Struktur ist einfach: ein Viewport und innen relativ positionierte UL mit links schwebenden LIs.

Ich habe ein Problem in einer solchen Situation konfrontiert:

  1. Der Benutzer klickt auf "zurück" Pfeil.
  2. JS hängt die richtige LI vor dem aktuell angezeigten LI-Knoten an.
  3. Vorläufig hat UL den CSS-Übergang als none 0s linear festgelegt, um Animationsänderungen zu verhindern. In diesem Moment reduziere ich den linken UL-CSS-Wert um die Slider-Breite (sagen wir: von 0px bis -1200px), um die gleiche Ansicht zu erhalten.
  4. Jetzt ändere ich die Übergangseigenschaft von UL zu all 0.2s ease-out.
  5. Jetzt ändere ich die linke Eigenschaft von UL, um die CSS3-Animation auszulösen. (sagen wir: von -1200px zu 0px).

Was ist das Problem? Browser vereinfacht Änderungen und macht keine Animationen.

Stoyan Stefanov schrieb über Reflow-Problem in seinem Blog , aber in diesem Fall funktioniert nicht versuchen, einen Reflow auf Element erzwingen.

Dies ist ein Stück Code ist dies zu tun (ich Browser-Präfixe zur Vereinfachung ausgelassen):

ul.style.transition = 'none 0s linear 0s'; ul.style.left = '-600px'; ul.style.transition = 'all 0.2s ease-out'; ul.style.left = '0px';

Hier Geige Problem in Aktion zu sehen: http://jsfiddle.net/9WX5b/1/

+0

Animationen auftreten, wenn eine Eigenschaft im CSS geändert wird. Es ist nicht notwendig, 'none 0s linear 'anzuwenden. Nichts wird animiert, bis Sie die Eigenschaft' left 'ändern. –

+1

Das Deaktivieren des Übergangs war wichtig, da ich die Position der älteren Folie nach dem Hinzufügen der neuen Folie unsichtbar fixieren musste. – Simon

Antwort

19

Anfordern der offsetHeight eines Elements macht alles gut. Sie können eine Reflow zwingen diese Funktion verwenden und es das Element passiert, dass Arten wurden geändert:

function reflow(elt){ 
    console.log(elt.offsetHeight); 
} 

Und nennen dies wo Rückfluesse benötigt werden. Siehe dieses Beispiel: http://jsfiddle.net/9WX5b/2/

EDIT: vor kurzem benötigt, um dies zu tun, und fragte mich, ob es einen besseren Weg als console.log es gab. Sie können nicht einfach elt.offsetHeight als eigene Anweisung schreiben, da der Optimierer (zumindest von Chrome) keinen Reflow auslöst, weil er nur auf eine Eigenschaft ohne Getter-Set zugreift, ohne sie überhaupt auswerten zu müssen. Also, AFAIK der billigste Weg, dies zu tun ist void(elt.offsetHeight), da es nicht sicher ist, ob void Nebenwirkungen hat oder nicht. (könnte übersteuert werden oder etwas, IDK).

+1

Danke, du hast mir den Tag gerettet!Außerdem habe ich translate3d (falls unterstützt) für glattere Animationen verwendet, und alles funktioniert in jedem Browser wie ein Zauber. Nochmals vielen Dank. – Simon

+3

Sie brauchen nicht einmal die 'console.log'. nur 'elt.offsetHeight' ist genug – HerrSerker

+1

Dies funktioniert nur auf Webkit-Browsern. – TrungDQ

0
function reflow(element) { 
    if (element === undefined) { 
     element = document.documentElement; 
    } 
    void(element.offsetHeight); 
} 

Es funktioniert OK mit Chrome und FF, und scheint die einfachste und tragbare Art und Weise, um es ATM zu tun. nur

Verwandte Themen