Аналог slideToogle() из jQuery на ванильном JS

Комментариев: 0
2 мин.
Добавить в закладки

В jQuery есть замечательная функция slideToogle(), которая позволяется реализовать эффект спойлера в одну строку. В данном посте я расскажу как реализовать ее аналог на чистом JavaScript.

Допустим, у нас есть такая HTML-разметка:

<ul>
  <li>
    <a href="#" class="parent-element">Родительский пункт</a>
    <!-- Стили лучше указать в отдельном файле. Это для примера -->
    <ul class="sub-menu" style="display: none;">
      <li>
        <a href="#">Дочерний пункт 1</a>
      </li>
      <li>
        <a href="#">Дочерний пункт 2</a>
      </li>
      <li>
        <a href="#">Дочерний пункт 3</a>
      </li>
    </ul>
  </li>
</ul>

Перед нами стоит задача реализовать эффект спойлера, который будет открывать дочернее меню при клике на родительский пункт и скрывать его при повторном клике. Если в проекте мы используем jQuery, то могли бы написать так:

$('.parent-element').on('click', function () {
  $(this).closest('li').next('.sub-menu').slideToggle();
});

Но если вы планировали добавлять jQuery в свой проект только для этой функции — зачем тянуть лишнюю библиотеку, если можно просто написать аналог этой функции на чистом JavaScript.

function slideToggle(elem, cls = 'open', animationSpeed = 300, timingFunction = 'ease-in-out') {
    if (!elem.classList.contains(cls)) {
        elem.classList.add(cls);
        elem.style.overflow = 'hidden';
        elem.style.height = 'auto';
        elem.style.transitionProperty = 'height';
        elem.style.transitionDuration = (animationSpeed / 1000) + 's';
        elem.style.transitionTimingFunction = timingFunction;
        const height = elem.clientHeight + 'px';
        elem.style.height = '0';
        setTimeout(function () {
            elem.style.height = height;
        }, 0);
    } else {
        elem.style.height = '0';
        setTimeout(function () {
            elem.classList.remove(cls);
        }, animationSpeed);
    }
}

Параметры функции:

  • elem — элемент, к которому нужно применить эффект слайдера;
  • cls — класс, который будет добавляться при раскрытии. Для этого класса вы указываете display: none или display: flex;
  • animationSpeed — скорость анимации в миллисекундах;
  • timingFuction — анимация эффекта перехода. Подробнее.

А вот пример использования:

const parentElements = document.querySelectorAll('.parent-element');
for (let parentElement of parentElements) {
  parentElement.addEventListener('click', function () {
    const subMenu = this.parentElement.querySelector('.sub-menu');
    slideToggle(subMenu);
  });
}

Аналог slideToogle() из jQuery на ванильном JS

Подписаться
Уведомить о
guest
0 комментариев