Не работает classList.add при клике на дочерний элемент
Есть примерно такой код:
HTML
<div class="portfolio">
<div class="op-portf">
<h2>ProgectName</h2>
</div>
<div class="descr">
<h3>site</h3>
<p>description</p>
</div>
<div class="pictures hidden">
<div class = "gallery-place">
<button class="close-pic">X</button>
<div class="pictures-collection">
<p>pic1</p>
<p>pic2</p>
<p>pic3</p>
<p>pic4</p>
</div>
</div>
</div>
</div>
<div class="portfolio">
<div class="op-portf">
<h2>ProgectName</h2>
</div>
<div class="descr">
<h3>site</h3>
<p>description</p>
</div>
<div class="pictures hidden">
<div class = "gallery-place">
<button class="close-pic">X</button>
<div class="pictures-collection">
<p>pic1</p>
<p>pic2</p>
<p>pic3</p>
<p>pic4</p>
</div>
</div>
</div>
</div>
<div class="portfolio">
<div class="op-portf">
<h2>ProgectName</h2>
</div>
<div class="descr">
<h3>site</h3>
<p>description</p>
</div>
<div class="pictures hidden">
<div class = "gallery-place">
<button class="close-pic">X</button>
<div class="pictures-collection">
<p>pic1</p>
<p>pic2</p>
<p>pic3</p>
<p>pic4</p>
</div>
</div>
</div>
</div>
CSS
.hidden{
display: none;
}
JS
const descr = document.querySelectorAll('.portfolio')
for (let openAndClose of descr) {
const gallery = openAndClose.children[2]//Список
const closeButton = openAndClose.children[2].children[0].children[0]//Кнопка "Х"
const openGallery = () => gallery.classList.remove("hidden")
const closeGallery = () => {gallery.classList.add("hidden"); console.log('click')}
openAndClose.addEventListener('click', openGallery)
closeButton.addEventListener('click', closeGallery)
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && !gallery.classList.contains("hidden")) closeGallery()})
}
Суть такова: при клике на каждый <div class="portfolio"> открывается некий уникальный список (функция openGallery). Соответственно при клике на кнопку "Х" в этом списке он должен закрываться (функция closeGallery). Но почему-то это не работает, список не закрывается. Ошибок никаких не выдаёт и если в функцию добавить какой-нибудь console.log, он выведется. Причём при добавлении этой функции в событие нажатия клавиши "Escape", список закроется. Помогите разобраться в чём дело?
Ответы (1 шт):
У вас срабатывает всплытие события. Поэтому при клике на крестик, события клика всплывает до корневого элемента, при клике на который должна открываться галерея. Как следствие она снова открывается и убирается класс. Надо использовать stopPropagation;
const descr = document.querySelectorAll('.portfolio')
for (let openAndClose of descr) {
let gallery = openAndClose.children[2]//Список
let closeButton = openAndClose.children[2].children[0].children[0]//Кнопка "Х"
const openGallery = () => gallery.classList.remove("hidden")
const closeGallery = (e) => {
e.stopPropagation(); // <-- Убираем дальнейшую передачу текущего события.
gallery.classList.add("hidden");
}
openAndClose.addEventListener('click', openGallery)
closeButton.addEventListener('click', closeGallery)
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && !gallery.classList.contains("hidden")) closeGallery()})
}
.hidden{
display: none;
}
<div class="portfolio">
<div class="op-portf">
<h2>ProgectName</h2>
</div>
<div class="descr">
<h3>site</h3>
<p>description</p>
</div>
<div class="pictures hidden">
<div class = "gallery-place">
<button class="close-pic">X</button>
<div class="pictures-collection">
<p>pic1</p>
<p>pic2</p>
<p>pic3</p>
<p>pic4</p>
</div>
</div>
</div>
</div>
<div class="portfolio">
<div class="op-portf">
<h2>ProgectName</h2>
</div>
<div class="descr">
<h3>site</h3>
<p>description</p>
</div>
<div class="pictures hidden">
<div class = "gallery-place">
<button class="close-pic">X</button>
<div class="pictures-collection">
<p>pic1</p>
<p>pic2</p>
<p>pic3</p>
<p>pic4</p>
</div>
</div>
</div>
</div>
<div class="portfolio">
<div class="op-portf">
<h2>ProgectName</h2>
</div>
<div class="descr">
<h3>site</h3>
<p>description</p>
</div>
<div class="pictures hidden">
<div class = "gallery-place">
<button class="close-pic">X</button>
<div class="pictures-collection">
<p>pic1</p>
<p>pic2</p>
<p>pic3</p>
<p>pic4</p>
</div>
</div>
</div>
</div>