При создании accrodion на JS работает только первая строка
Создаю accrodion на чистом JavaScript с анимацией. Проблема в том, что только первая строка работает как мне надо, остальные не открываются:
let slideUp = (target, duration = 500) => {
target.style.transitionProperty = 'height, margin, padding';
target.style.transitionDuration = duration + 'ms';
target.style.boxSizing = 'border-box';
target.style.height = target.offsetHeight + 'px';
target.offsetHeight;
target.style.overflow = 'hidden';
target.style.height = 0;
target.style.paddingTop = 0;
target.style.paddingBottom = 0;
target.style.marginTop = 0;
target.style.marginBottom = 0;
window.setTimeout(() => {
target.style.display = 'none';
target.style.removeProperty('height');
target.style.removeProperty('padding-top');
target.style.removeProperty('padding-bottom');
target.style.removeProperty('margin-top');
target.style.removeProperty('margin-bottom');
target.style.removeProperty('overflow');
target.style.removeProperty('transition-duration');
target.style.removeProperty('transition-property');
}, duration);
}
let slideDown = (target, duration = 500) => {
target.style.removeProperty('display');
let display = window.getComputedStyle(target).display;
if (display === 'none')
display = 'block';
target.style.display = display;
let height = target.offsetHeight;
target.style.overflow = 'hidden';
target.style.height = 0;
target.style.paddingTop = 0;
target.style.paddingBottom = 0;
target.style.marginTop = 0;
target.style.marginBottom = 0;
target.offsetHeight;
target.style.boxSizing = 'border-box';
target.style.transitionProperty = "height, margin, padding";
target.style.transitionDuration = duration + 'ms';
target.style.height = height + 'px';
target.style.removeProperty('padding-top');
target.style.removeProperty('padding-bottom');
target.style.removeProperty('margin-top');
target.style.removeProperty('margin-bottom');
window.setTimeout(() => {
target.style.removeProperty('height');
target.style.removeProperty('overflow');
target.style.removeProperty('transition-duration');
target.style.removeProperty('transition-property');
}, duration);
}
let slideToggle = (target, duration = 500) => {
if (window.getComputedStyle(target).display === 'none') {
return slideDown(target, duration);
} else {
return slideUp(target, duration);
}
}
var accordionTitle = document.querySelector('.accordion-title');
accordionTitle.addEventListener('click', function () {
slideToggle(document.querySelector('.collapse'), 400);
accordionTitle.classList.toggle('collapsed');
});
.collapse:not(.show) {
display: none;
}
<div class="accordion-card">
<button class="accordion-title collapsed">
Значения параметров
</button>
<div class="collapse">
<p>
Аргумент должен соответствовать допустимой строке селектора, содержащей один или несколько селекторов. При указании нескольких селекторов необходимо разделять значения запятыми. Если по какой-то причине вы используете в наименовании селекторов символы,
которые не являются частью стандартного синтаксиса CSS, то при поиске такие символы должны быть экранированы с помощью символа обратной косой черты ("\"). Поскольку обратная косая черта также является специальным символом (escape) в JavaScript,
то при вводе литеральной строки ее необходимо экранировать дважды. Обязательный параметр.
</p>
</div>
</div>
<div class="accordion-card">
<button class="accordion-title collapsed">
Исключения
</button>
<div class="collapse">
<p>
Возникает в том случае, если синтаксис указанного селектора или селекторов некорректен.
</p>
</div>
</div>
<div class="accordion-card">
<button class="accordion-title collapsed">
Результат нашего примера:
</button>
<div class="collapse">
<p>
В этом примере с использованием атрибута событий onclick при нажатии на кнопку (HTML элемент) вызываем функцию myFunc(), которая с использованием JavaScript метода document.querySelectorAll() выбирает все элементы с классом block и инициализируем переменную
этим значением (объект NodeList). После этого мы проходим циклом по всем элементам этого массивоподобного объекта (объект NodeList) и устанавливаем зеленый цвет текста каждому элементу.
</p>
</div>
</div>
Уверен проблема в этом куске:
accordionTitle.addEventListener('click', function () {
slideToggle(document.querySelector('.collapse'), 400);
accordionTitle.classList.toggle('collapsed');
});
Ответы (1 шт):
Автор решения: DemoS
→ Ссылка
Строкой var accordionTitle = document.querySelector('.accordion-title'); вы берете как раз только первый элемент и вешаете на него прослушку клика, потому так и происходит. Вам нужно вешать на все, то есть и брать все посредством document.querySelectorAll. А в обработчике что-то вроде брать следующий элемент (который собственно и нужно свернуть/развернуть) через https://developer.mozilla.org/ru/docs/Web/API/Node/nextSibling
В общем немного подправил ваш код
let slideUp = (target, duration = 500) => {
target.style.transitionProperty = 'height, margin, padding';
target.style.transitionDuration = duration + 'ms';
target.style.boxSizing = 'border-box';
target.style.height = target.offsetHeight + 'px';
target.offsetHeight;
target.style.overflow = 'hidden';
target.style.height = 0;
target.style.paddingTop = 0;
target.style.paddingBottom = 0;
target.style.marginTop = 0;
target.style.marginBottom = 0;
window.setTimeout(() => {
target.style.display = 'none';
target.style.removeProperty('height');
target.style.removeProperty('padding-top');
target.style.removeProperty('padding-bottom');
target.style.removeProperty('margin-top');
target.style.removeProperty('margin-bottom');
target.style.removeProperty('overflow');
target.style.removeProperty('transition-duration');
target.style.removeProperty('transition-property');
}, duration);
}
let slideDown = (target, duration = 500) => {
target.style.removeProperty('display');
let display = window.getComputedStyle(target).display;
if (display === 'none')
display = 'block';
target.style.display = display;
let height = target.offsetHeight;
target.style.overflow = 'hidden';
target.style.height = 0;
target.style.paddingTop = 0;
target.style.paddingBottom = 0;
target.style.marginTop = 0;
target.style.marginBottom = 0;
target.offsetHeight;
target.style.boxSizing = 'border-box';
target.style.transitionProperty = "height, margin, padding";
target.style.transitionDuration = duration + 'ms';
target.style.height = height + 'px';
target.style.removeProperty('padding-top');
target.style.removeProperty('padding-bottom');
target.style.removeProperty('margin-top');
target.style.removeProperty('margin-bottom');
window.setTimeout(() => {
target.style.removeProperty('height');
target.style.removeProperty('overflow');
target.style.removeProperty('transition-duration');
target.style.removeProperty('transition-property');
}, duration);
}
let slideToggle = (target, duration = 500) => {
if (window.getComputedStyle(target).display === 'none') {
return slideDown(target, duration);
} else {
return slideUp(target, duration);
}
}
var accordionTitles = document.querySelectorAll('.accordion-title');
accordionTitles.forEach( e => {e.addEventListener('click', function (s) {
slideToggle(s.target.nextSibling.nextElementSibling, 400);
s.target.classList.toggle('collapsed');
})});
.collapse:not(.show) {
display: none;
}
<div class="accordion-card">
<button class="accordion-title collapsed">
Значения параметров
</button>
<div class="collapse">
<p>
Аргумент должен соответствовать допустимой строке селектора, содержащей один или несколько селекторов. При указании нескольких селекторов необходимо разделять значения запятыми. Если по какой-то причине вы используете в наименовании селекторов символы,
которые не являются частью стандартного синтаксиса CSS, то при поиске такие символы должны быть экранированы с помощью символа обратной косой черты ("\"). Поскольку обратная косая черта также является специальным символом (escape) в JavaScript,
то при вводе литеральной строки ее необходимо экранировать дважды. Обязательный параметр.
</p>
</div>
</div>
<div class="accordion-card">
<button class="accordion-title collapsed">
Исключения
</button>
<div class="collapse">
<p>
Возникает в том случае, если синтаксис указанного селектора или селекторов некорректен.
</p>
</div>
</div>
<div class="accordion-card">
<button class="accordion-title collapsed">
Результат нашего примера:
</button>
<div class="collapse">
<p>
В этом примере с использованием атрибута событий onclick при нажатии на кнопку (HTML элемент) вызываем функцию myFunc(), которая с использованием JavaScript метода document.querySelectorAll() выбирает все элементы с классом block и инициализируем переменную
этим значением (объект NodeList). После этого мы проходим циклом по всем элементам этого массивоподобного объекта (объект NodeList) и устанавливаем зеленый цвет текста каждому элементу.
</p>
</div>
</div>