Не-jQuery: получение высоты, даже если максимальная высота равна нулю

#javascript

#javascript

Вопрос:

Этот код работает нормально.

Что я здесь делаю, так это преувеличиваю максимальную высоту класса active, но что мне нужно, так это указать точную высоту, чтобы иметь возможность запускать эффект с той же скоростью.

Для этого примера. Я не пишу динамическую панель навигации, и это отсутствие условия, но я думаю, что оно охватывает то, что я хочу указать.

Если вы нажмете на w33racleвы увидите в консоли, что там есть число. Однако 0 — это не то значение, которое мне было нужно. Я хочу, чтобы это была высота ul.выпадающий список.active независимо от того, имеет он класс .active или нет

 let test_clicker = document.getElementById('testClicker');

test_clicker.onclick = (e) => {
  let self = e.target || e.srcElement,
      s_s = self.nextElementSibling.classList;
  
  s_s.contains('active') ? s_s.remove('active') : s_s.add('active');
  
  console.log(self.nextElementSibling.clientHeight);
}  
 .dropdown {
  max-height: 0;
  overflow: hidden;
  transition: all 0.3s ease-in-out; }

.dropdown.active {
  max-height: 500px; }  
 <ul>
  <li>
    <a id="testClicker">w33racle</a>
    <ul class="dropdown">
      <li><a>This</a><li>
      <li><a>is</a><li>
      <li><a>for</a><li>
      <li><a>sample</a><li>
      <li><a>only</a><li>
    </ul>
  </li>
</ul>  

Любая помощь была бы оценена. Спасибо

Ответ №1:

Вы можете легко получить это, добавив высоту дочерних элементов.

Воспользуйтесь преимуществами, которые дал вам javascript. В этом случае вам не нужно animationend .

 let test_clicker = document.getElementById('testClicker'),
    thisIsTheHeight = 0;

test_clicker.onclick = (e) => {
  thisIsTheHeight = 0;
  let self = e.target || e.srcElement,
      s_s = self.nextElementSibling.classList;
  
  s_s.contains('active') ? s_s.remove('active') : s_s.add('active');
  
  [].forEach.call(self.nextElementSibling.children, (elem) => {
    thisIsTheHeight  = elem.clientHeight;
  });
  
  console.log(thisIsTheHeight);
}  
 .dropdown {
  max-height: 0;
  overflow: hidden;
  transition: all 0.3s ease-in-out; }

.dropdown.active {
  max-height: 500px; }  
 <ul>
  <li>
    <a id="testClicker">w33racle</a>
    <ul class="dropdown">
      <li><a>This</a><li>
      <li><a>is</a><li>
      <li><a>for</a><li>
      <li><a>sample</a><li>
      <li><a>only</a><li>
    </ul>
  </li>
</ul>  

Ответ №2:

Проблема здесь в том, что JavaScript завершается до завершения воспроизведения вашего перехода CSS.

Посмотрите на событие «transitionend»

Быстрым решением было бы либо удалить CSS-переход, либо добавить setTimeout с задержкой, равной длине CSS-перехода. Тем не менее, я рекомендую использовать событие transitionend, если оно подходит.

РЕДАКТИРОВАТЬ с примером реализации:

 let test_clicker = document.getElementById('testClicker');

test_clicker.onclick = (e) => {
  let self = e.target || e.srcElement,
      s_s = self.nextElementSibling.classList;
  
  s_s.contains('active') ? s_s.remove('active') : s_s.add('active');

}

document.querySelectorAll("ul.dropdown").forEach(function(element){
  element.addEventListener("transitionend", function(){
    console.log(element.clientHeight);
    console.log("transition ended")
  });
});  
 .dropdown {
  max-height: 0;
  overflow: hidden;
  transition: all 0.3s ease-in-out; }

.dropdown.active {
  max-height: 500px; }  
 <ul>
  <li>
    <a id="testClicker">w33racle</a>
    <ul class="dropdown">
      <li><a>This</a><li>
      <li><a>is</a><li>
      <li><a>for</a><li>
      <li><a>sample</a><li>
      <li><a>only</a><li>
    </ul>
  </li>
</ul>  

Комментарии:

1. transitionend это правильный путь. Вы не должны и не можете полагаться на тайм-аут, чтобы убедиться, что переход полностью завершен

2. @HermLuna — Конечно, до добавления класса высота все равно будет равна 0… Смотрите мой отредактированный ответ, возможно, теперь понятно, что я имел в виду?

3. @HermLuna — Отредактировано еще раз, чтобы исправить ошибку. Я использую querySelectorAll в случае, если у вас есть несколько выпадающих списков на странице, но это всего лишь пример, чтобы показать вам, что я имею в виду.

4. Вы сказали, что хотите, чтобы он всегда выдавал вам высоту ul. выпадающий список, который динамически изменяется. Вы не говорили, что всегда хотели, чтобы это давало вам увеличенную высоту.

5. Высота ul. выпадающий список не всегда равен 180. Когда у него нет класса .active, высота действительно равна 0. Если другой ответ — это то, что вы искали, теперь я понимаю ваш вопрос, не беспокойтесь. 🙂 Я бы сказал: «Я хочу, чтобы это была высота ul. выпадающий список.active независимо от того, имеет он класс .active или нет »