Почему переход CSS3 не работает на заданной высоте элемента с помощью JavaScript? - PullRequest
0 голосов
/ 06 июня 2018

Я написал фрагмент кода для создания аккордеона, чтобы вы могли увидеть код здесь .Есть некоторый HTML-код:

<div class="accordion_holder">
  <div class="accordion_item">
    <div class="title" onclick="toggle_accordion(this);">
      title 1 here
    </div>
    <div class="content">
      content here
    </div>
  </div>
  <div class="accordion_item">
    <div class="title" onclick="toggle_accordion(this);">
      title 2 here
    </div>
    <div class="content">
      content 2 here
    </div>
  </div>
</div>

И у меня есть ниже CSS для имитации аккордеонного перехода:

.accordion_holder .content {
    height: 0px;
    overflow: hidden;
    -webkit-transition: height 0.5s linear;
    -moz-transition: height 0.5s linear;
    -ms-transition: height 0.5s linear;
    -o-transition: height 0.5s linear;
    transition: height 0.5s linear;
}

И я устанавливаю высоту контента на 0px или offsetHeight используя этот фрагмент кода JavaScript:

function toggle_accordion(clicked_element) {
  var father = closest_parent(clicked_element, 'accordion_item');
  console.log(father);
  var accordion_content = father.getElementsByClassName("content")[0];
  var destination = 0;

  var current_height = accordion_content.offsetHeight;

  if (current_height == 0)
  {
    accordion_content.style.height = "auto";
    destination = accordion_content.offsetHeight;

    accordion_content.style.height = "0px";
  }
  console.log("destination is:", destination);
  accordion_content.style.height = destination+"px";
}

/************************************
 ** Find Closest Parent with Class **
 ***********************************/
function closest_parent (current_element, class_name) {
    var parent = current_element.parentElement;
    if (parent) {
        if (parent.className.indexOf(class_name) >= 0)
        {
            //We found requested parent
            return parent;
        }
        else
        {
            return closest_parent (parent, class_name);
        }
    }
    else
    {
        return false;
    }
}

Правильно работает высота элемента содержимого.когда он закрывается (установите высоту элемента Content на 0px), он будет двигаться плавно и эффект перехода работает.но когда он открывается (установите высоту элемента Content на offsetHeight), переход не будет работать.Можете ли вы указать мне, что не так?

1 Ответ

0 голосов
/ 06 июня 2018

Это потому, что вы устанавливаете высоту auto , а затем пытаетесь получить ее offsetHeight.

Получение offsetHeight запускает перекомпоновку , поэтому он уже собирается разметить страницу и попытаться перейти на height: auto;Поскольку переходы на height: auto не работают, он будет прыгать прямо на целевую высоту.Затем, когда вы устанавливаете высоту элемента равной значению, которое вы получили от offsetHeight, элемент уже имеет эту высоту, поэтому переход не будет.

Два способа исправить это:

Более хакерский способ - повернуть оплавление, вызванное offsetHeight, в свою пользу: просто попробуйте получить значение снова после того, как верните высоту обратно в 0, снова запустив оплавление:

if (current_height == 0)
  {
    accordion_content.style.height = "auto";
    destination = accordion_content.offsetHeight;

    accordion_content.style.height = "0px";
    // Here is the trick:
    accordion_content.offsetHeight // triggers a reflow
  }

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

...