Animacja płynnej zmiany wysokości elementu po podmianie jego wnętrza

0

Bry.

Powiedzmy że mam takie coś:

<button id="tg">CLICK ME</button><br>
<div id="adjustHeightDiv">
  <span id="s1">
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
  </span>
  <span id="s2">
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
  </span>
  <span id="s3">
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
    adfgurf98yt32bkjfd<br>
  </span>
  </div>

i teraz chcę, żeby po zmianie s1_span.style.display = "none"; oraz np. s2_span.style.display = "inline"; mój div się rozszerzał w czasie dostosowując się do wysokości spana (płynnie)
Mam zdefiniowane odpowiednie onclick dla elementu, który switchuje spany i zmienia ich widoczność. Jednak:

  document.getElementById("adjustHeightDiv").style.transition = "height 1s";

Nie daje efektu. Co robię źle?

https://jsfiddle.net/a3Lxbjn4/10/

0

możesz popróbować z tym, żeby ustawić każdemu elementowi display: block, overflow: hidden oraz manipulować właściwością max-height (i ustawić efekt przejścia na max-height właśnie - jak jest 0px to schowany, jak np. 1000px to się pokazuje).

0

CSS odpala transition jedynie w momencie jak styl zmieni się ręcznie przez CSS, nie zadziała to w taki dynamiczny sposób jak opisałeś, więc jeśli chcesz to animować tak jak mówisz musiałbyś za każdym razem pobierać wysokość wszystkich spanów i ręcznie zmieniać height temu divowi.

function calculateAllHeight() {
 // tutaj pobierasz wszystkie spany i zapisujesz wysokość
}

// i przy każdym kliknięciu odpalasz tą funkcję i przypisujesz wynik przez style
document.getElementById("adjustHeightDiv").style.height = calculateAllHeight() + "px";
0

Aha. Nie wiem czemu, ale ustawienie height na sztywno, czy to na 0% czy 0px nic nie daje. Czemu?

https://jsfiddle.net/szgpen6o/4/

1

Nie jest to zbyt najlepszy przykład, bo można to zrobić o wiele lepiej, ale do rzeczy.

Jeśli chcesz animować spany, a nie diva, to musisz im nadać display: block;, bo muszą być oznaczone jako element blokowy, później overflow: hidden, żeby ukryć tekst podczas zmiany wysokości i transition, żeby ustawić animację.

Po kliknięciu w przycisk ustawiasz najpierw wszystkim elementom odpowiednie max-height/height zależnie od efektu.

Wszystkie zasady odnośnie styli są takie same jakbyś pisał normalny kod CSS.

var start = -1;

for (let i = 1; i <=3; i++) {
    const span = document.getElementById('s' + i);
   
    if (span) {
      span.style.display = "block";
      span.style.overflow = "hidden";
      span.style.transition = "max-height 1s ease";
    }  
}
 
function toggle() {
  var ids = ["s1", "s2", "s3"];
  
  for (var i = 0; i < ids.length; i++) {
    document.getElementById(ids[i]).style.maxHeight = "0px";
  }
  
  start = (start + 1) % 3;
  document.getElementById(ids[start]).style.maxHeight = "250px";
}

document.getElementById("tg").addEventListener("click", toggle);
toggle();
0

Dziękuję

@Xarviel skąd czerpiesz wiedzę? Czy umiesz po prostu bardzo dokładnie czytać z sieci czy uczyłeś się z książek czy tutor w firmie?

0

Bardzo dziękuję. Mam jednak jedną uwagę:
https://jsfiddle.net/szgpen6o/4/

Powyżej kod po zastosowaniu rad kolegi @Xarviel . Działa. Ale uzyskujemy efekt jednoczesnego zwijania i rozwijania 2 elementów. A ja chciałbym, aby mieć taki efekt:

  1. Na początku wyświetla się jeden element (domyślny)
  2. Po kliknięciu na przycisk zawartość elementu jest podmieniana, ale w taki sposób, że jego stary rozmiar (ilość wyświetlanego tekstu) jest zachowany
  3. Następnie, jeżeli nowa ilość tekstu jest większa, względem starego elementu, element się rozszerza do nowego rozmiaru. A jeżeli jest mniejsza, to zmniejsza się.
  4. I koniecznie, nie wyświetlają się jednocześnie 2 spany i nie zmieniają się ich rozmiary na oczach usera.

Da radę takie coś zrobić? :P

0

Po trudach udało się. Co prawda zaprzęgłem jQuery ale działa :D

https://jsfiddle.net/8ewh7crk/53/

PS. Trzeba jeszcze dodać semafor, żeby nowe kliknięcie nie powodowało uruchomienia nowego wywołania w trakcie aktualnego. Ale z tym już dam sobie radę.

Dzięki ;)

1

Można za pomocą css to chyba zrobić prościej, no i bez jQuery (i semaforów :))
https://jsfiddle.net/92axn5q6/1/

0

@m31: dziękuję. Twoja wersja działa ale nie spełnia założenia. Przeglądam na telefonie i słabo mogę zobaczyć kod w całości ale Twoja wersja nie jest tranzycją, a mnie zależało na animacji ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1