Создание аналога slideToggle() на чистом JavaScript

В этой статье рассмотрим как реализовать аналог jQuery метода slideToggle() на чистом JavaScript.
Что такое slideToggle()?
slideToggle()
– это метод в библиотеке jQuery, который используется для плавного показа или скрытия контента элемента.
Пример реализации подобного функционала на чистом JavaScript приведён на GitHub: collapse. Выполнен он через класс ItcCollapse
.

Подключение и использования ItcCollapse
1. Подключить CSS и JavaScript файлы к странице:
<link rel="stylesheet" href="css/collapse.css">
<script src="js/collapse.js"></script>
2. Обернуть элементы, контент которых необходимо плавно показывать/скрывать в <div class="collapse"></div>
:
<div class="collapse">
<div class="collapse__body">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Aspernatur obcaecati animi corrupti, numquam
explicabo maxime recusandae cupiditate amet velit sequi soluta nostrum vel consequuntur consectetur
repellendus quia doloremque itaque eum!</p>
</div>
</div>
Элемент <div class="collapse"></div>
является обёрткой, к нему никаких стилей добавлять не нужно.
По умолчанию содержимое такого элемента не показывается. Если необходимо чтобы элемент изначально отображал содержимое, то к нему необходимо добавить класс collapse_show
.
<div class="collapse collapse_show">
...
</div>
Добавлять оформление (границы, padding и т.д.) необходимо к элементу расположенному в .collapse
. В приведённом выше примере – это элемент .collapse-body
.
Например:
.collapse__body {
background-color: #fff;
border: 5px solid rgba(139, 195, 74, .5);
border-radius: 0.25rem;
padding: 1rem;
}
3. Инициализировать нужные элементы как ItcCollapse
:
// получаем элемент
const el = document.querySelector('.collapse');
// инициализируем его как ItcCollapse
const collapse = new ItcCollapse(el);
4. Использовать методы show()
, hide()
и toggle()
для переключения видимости элемента:
// показать контент
collapse.show();
// скрыть контент
collapse.hide();
// переключить видимость контента
collapse.toggle();
Пример JavaScript кода для переключения видимости элемента .collapse
при нажатии на кнопку #toggle
:
// получаем элемент
const el = document.querySelector('.collapse');
// инициализируем его как ItcCollapse
const collapse = new ItcCollapse(el);
// при клике на #toggle
document.querySelector('#toggle').onclick = () => {
// переключаем видимость контента el
collapse.toggle();
}
Как внутри устроен ItcCollapse?
Код JavaScript состоит из класса ItcCollapse
:
class ItcCollapse {
constructor(target, duration = 350) {
this._target = target;
this._duration = duration;
}
show() {
// ...
}
hide() {
// ...
}
toggle() {
// ...
}
}
Конструктор принимает 2 аргумента и сохраняет их в this._target
и this._duration
. Первый аргумент указывает на элемент, контент которого нужно показывать или скрывать с анимацией. Второй аргумент задаёт её длительность (по умолчанию она составляет 350 миллисекунд).
Метод show()
выполняет показ контента элемента this._target
с эффектом «скольжение вниз»:
show() {
const el = this._target;
// завершаем работу метода, если элемент содержит класс collapsing или collapse_show
if (el.classList.contains('collapsing') || el.classList.contains('collapse_show')) {
return;
}
// удаляем класс collapse
el.classList.remove('collapse');
// сохраняем текущую высоту элемента в константу height (это значение понадобится ниже)
const height = el.offsetHeight;
// устанавливаем высоте значение 0
el.style['height'] = 0;
// не отображаем содержимое элемента, выходящее за его пределы
el.style['overflow'] = 'hidden';
// создание анимации скольжения с помощью CSS свойства transition
el.style['transition'] = `height ${this._duration}ms ease`;
// добавляем класс collapsing
el.classList.add('collapsing');
// получим значение высоты (нам этого необходимо для того, чтобы просто заставить браузер выполнить перерасчет макета, т.к. он не сможет нам вернуть правильное значение высоты, если не сделает это)
el.offsetHeight;
// установим в качестве значения высоты значение, которое мы сохранили в константу height
el.style['height'] = `${height}px`;
// по истечении времени анимации this._duration
window.setTimeout(() => {
// удалим класс collapsing
el.classList.remove('collapsing');
// добавим классы collapse и collapse_show
el.classList.add('collapse');
el.classList.add('collapse_show');
// удалим свойства height, transition и overflow
el.style['height'] = '';
el.style['transition'] = '';
el.style['overflow'] = '';
}, this._duration);
}
Метод hide()
выполняет плавное скрытие контента this._target
с эффектом «скольжение вверх»:
hide() {
// сохраняем элемент в константу el
const el = this._target;
// завершаем работу метода, если элемент содержит класс collapsing или collapse_show
if (el.classList.contains('collapsing') || !el.classList.contains('collapse_show')) {
return;
}
// установим свойству height текущее значение высоты элемента
el.style['height'] = `${el.offsetHeight}px`;
// получим значение высоты
el.offsetHeight;
// установим CSS свойству height значение 0
el.style['height'] = 0;
// обрежем содержимое, выходящее за границы элемента
el.style['overflow'] = 'hidden';
// добавим CSS свойство transition для осуществления перехода длительностью this._duration
el.style['transition'] = `height ${this._duration}ms ease`;
// удалим классы collapse и collapse_show
el.classList.remove('collapse');
el.classList.remove('collapse_show');
// добавим класс collapsing
el.classList.add('collapsing');
// после завершения времени анимации
window.setTimeout(() => {
// удалим класс collapsing
el.classList.remove('collapsing');
// добавим класс collapsing
el.classList.add('collapse');
// удалим свойства height, transition и overflow
el.style['height'] = '';
el.style['transition'] = '';
el.style['overflow'] = '';
}, this._duration);
}
Метод toggle()
предназначен для переключения видимости элемента в зависимости от его состояния:
toggle() {
this._target.classList.contains('collapse_show') ? this.hide() : this.show();
}
Работает метод toggle()
очень просто. Он проверяет у элемента наличие класса collapse_show
. Если он имеется, то вызывает метод hide()
, иначе show()
.
В каждом состоянии элемент .collapse
имеет определённые классы:
collapse
– содержимое скрыто;collapsing
– во время CSS-переходовcollapse
иcollapse_show
– содержимое открыто.
При открытии содержимого:

При закрытии содержимого будет происходить наоборот: collapse
и .collapse_show
-> collapsing
-> collapse
.