Переход высоты CSS и JS от неустановленного к определенному значению

У меня есть элемент с неустановленной высотой. Я хочу, чтобы высота плавно переходила в желаемое значение (например, 200 пикселей). Я использую для этого requestAnimationFrame, но не могу понять, как именно это работает.

В приведенном ниже примере, если мы раскомментируем первый requestAnimationFrame и его закрывающие скобки, он будет работать именно так, как мы хотим. Но почему?

Да, я понимаю, что таким образом первое изменение высоты будет завернуто в свой собственный requestAnimationFrame, но ключевой вопрос в том, почему это имеет такое большое значение? Тем более, что второе изменение высоты уже завернуто в requestAnimationFrame. Разве это уже не делает его как бы разделенным во времени, кроме первого изменения?

Я прочитал несколько статей о requestAnimationFrame, но все еще не мог понять этот конкретный пример. Я думаю, мне нужно какое-то ручное объяснение здесь.

Пожалуйста помоги.

РЕДАКТИРОВАТЬ после получения ответа:

Это редактирование основано на ответе бархатсора.

Итак, в основном в исходном примере последовательность действий выглядит так (поправьте меня, если я не прав):

Кадр 1, действие 1. (сразу). Узнать реальную высоту элемента в пикселях
Кадр 1, действие 2. (сразу). Установите высоту элемента на его scrollHeight
Кадр 1, действие 3. (сразу). Измените высоту элемента на 200 пикселей (немедленное изменение приводит к объединению изменений)
Кадр 2, действие 1. (на следующем кадре). Браузер, когда будете готовы, анимируйте (изменения объединены — анимировать нечего)

Если мы раскомментируем первый requestAnimationFrame и его закрывающие скобки, будет ли это выглядеть так?

Кадр 1, действие 1. (сразу). Узнать реальную высоту элемента в пикселях
Кадр 1, действие 2. (сразу). Установите высоту элемента на его scrollHeight
Кадр 2, действие 1. (на следующем кадре). Браузер, когда будешь готов, анимируй
Кадр 2, действие 2. (сразу). Измените высоту элемента на 200px (изменения теперь разделены по времени на один кадр?)
Кадр 3, действие 1. (на следующем кадре). Браузер, когда будете готовы, анимируйте (анимация меняется)

Это верно? Я хотел бы увидеть вашу точку зрения на это. Может я совсем не прав?

let button = document.querySelector(".button");
let element = document.querySelector(".element");

button.addEventListener("click", triggerHeightChange);

function triggerHeightChange() {
  // finding out real height of the element in pixels
  let actualHeight = element.scrollHeight; 
  
 // requestAnimationFrame(function() {
    // assgning height value so we aren't transitioning out of "auto"
    element.style.height = actualHeight + "px"; 
 
    requestAnimationFrame(function() {
      // assigning desired height value
      element.style.height = "200px"; 
    })
 // })
 
  // this part is just to return element to it's initial state after transition
  element.addEventListener("transitionend", function() {
    element.style.height = actualHeight + "px";
    element.addEventListener("transitionend", function() {
      element.removeAttribute("style");
    }, {once: true})
  }, {once: true})
}
.element {
  width: max-content;
  margin: 0 auto 30px;
  font-size: 40px;
  background-color: gold;
  transition: 0.5s height;
}

.button {
  display: block;
  margin: 0 auto 30px;
  font-size: 20px;
}
<div class = "element">Element with an unset height</div>

<button class = "button">Change element's height from unset to 200px with smooth transition, then return it back</button>
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
368
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы устанавливаете высоту элемента на scrollHeight, а затем сразу же меняете ее на 200px.

Большинство браузеров оптимизируют переходы и объединяют изменения, которые занимают менее 16 мс, поэтому переход не отображался.

Таким образом, решение состоит в том, чтобы указать браузеру анимировать, когда он будет готов, используя requestAnimationFrame(), как в вашем коде.

https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

Другие вопросы по теме