Плавное открытие блока Div под нажимаемой ссылкой

есть рабочий пример на JS открытия блока под нажимаемой ссылкой. Но как сделать так, чтобы этот блок открывался плавно c какой-нибудь анимацией? Анимация на CSS не срабатывает. Как можно реализовать с помощью javascript?

document.querySelectorAll('a').forEach(function(link) {
    link.addEventListener('click', function(e) {
        e.preventDefault(); // Предотвратить поведение ссылки по умолчанию
        var Div = document.querySelector('.div'); // Получаем div
        this.parentNode.insertBefore(Div, this.nextSibling); // Вставить div после нажатой ссылки
        Div.classList.add('open'); // Показать только что вставленный div
    });
});
a { display: block }
.div {
    position: relative; width: 250px; height: 0; opacity: 0; visibility: hidden; padding: 1em; background: #BCC5C8;
    -webkit-transition: 0.3s all; -moz-transition: 0.3s all; -o-transition: 0.3s all; -ms-transition: 0.3s all; transition: 0.3s all;
}
.div.open {height: auto; opacity: 1; visibility: visible;}
<a href="#" id="a">cсылка 1</a>
<a href="#" id="b">cсылка 2</a>
<a href="#" id="c">cсылка 3</a>

<div class="div">my div</div>


Ответы (1 шт):

Автор решения: ksa

Но как сделать так, чтобы этот блок открывался плавно c какой-нибудь анимацией?

Предложу вот такой вариант "анимации" при скрытии и показе блока...

document.querySelectorAll('a').forEach(function(link) {
  var Div = document.querySelector('.div'); // Получаем div
  link.addEventListener('click', function(e) {
    e.preventDefault();
    const o = Div.classList
    // проверяю виден блок или нет
    if (o.contains('open')) {
      // виден
      // значит его нужно анимированно скрыть
      Div.style.height = 0
      o.remove('open');
      const self = this
      // "одноразовый" обработчик на завершение анимации скрытия
      Div.addEventListener('transitionend', _ => on(self), { once: true })
    } else {
      // не виден
      on(this)
    }
  });
  // анимированный показ блока в нужном месте
  function on(obj) {
    // вставить блок после указанного объекта
    obj.insertAdjacentElement('afterend', Div)
    // сделать видимым
    Div.style.height = Div.scrollHeight + 'px'
    Div.classList.add('open');
  }
});
a {
  display: block
}

.div {
  position: relative;
  width: 250px;
  height: 0;
  opacity: 0;
  padding: 1em;
  background: #BCC5C8;
  -webkit-transition: 0.3s all;
  -moz-transition: 0.3s all;
  -o-transition: 0.3s all;
  -ms-transition: 0.3s all;
  transition: 0.3s all;
  /*
  visibility: hidden;
  */
}

.div.open {
  opacity: 1;

  /*
  height: auto;
  visibility: visible;
  */
}
<a href="#" id="a">cсылка 1</a>
<a href="#" id="b">cсылка 2</a>
<a href="#" id="c">cсылка 3</a>

<div class="div">my div</div>

→ Ссылка