在展开的网格项上关闭按钮不起作用



所以我有一个简单的3列网格和每个网格项目有一个关闭按钮和一个图像。当我点击一个网格项目时,图像将展开,并出现关闭按钮。

如果您单击另一个网格项,当前展开的网格项将恢复正常,新单击的网格项将展开,或者,如果您单击关闭按钮,当前展开的网格项将简单地恢复正常。我这样做的方式是简单地通过添加和删除一个类与classList函数在javascript。

我有所有的工作,除了关闭按钮;它实际上并没有使网格项目恢复正常,即使控制台日志的输出不显示我添加的类,因为当你单击关闭按钮时它被删除了(因为它应该),所以我真的很困惑。

下面是我的代码:

document.addEventListener("DOMContentLoaded", function(e) {
const containers = document.querySelectorAll('.container');
let previouslyClickedContainer = '';
containers.forEach(container => {
const closeBtn = container.querySelector('.close-btn');
container.addEventListener('click', () => {
if (previouslyClickedContainer !== '') {
previouslyClickedContainer.classList.remove('enlarge');
}
container.classList.add('enlarge');
previouslyClickedContainer = container;
if (closeBtn.getAttribute('aria-pressed') === 'true') {
closeBtn.setAttribute('aria-pressed', 'false');
}
});
closeBtn.addEventListener('click', () => {
container.classList.remove('enlarge');
previouslyClickedContainer = '';
closeBtn.setAttribute('aria-pressed', 'true');
});
});
});
.main-grid {
gap: 5rem;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
grid-auto-rows: minmax(350px, 1fr);
}
.container {
position: relative;
z-index: 99;
width: 100%;
height: 100%;
cursor: pointer;
transition: all 600ms ease-in-out;
}
.container .close-btn {
position: absolute;
z-index: 101;
inset-inline-end: 0;
margin-block-start: 1.25rem;
margin-inline-end: .5rem;
opacity: 0;
transition: opacity 600ms ease-in-out;
}
.container img {
height: 100%;
}

/* class that is added and removed */
.enlarge {
z-index: 100;
width: 150%;
height: 150%;
box-shadow: 0px 0px 12px 0px hsl( var(--clr-dark) / .6);
}
.enlarge .close-btn {
opacity: 1;
}
.close-btn {
position: relative;
width: 32px;
transform: rotate(45deg);
}
.close-btn,
.close-btn::after {
height: 2px;
background-color: white;
}
.close-btn::after {
content: '';
position: absolute;
inset-inline: 0;
top: -.5rem;
transform: rotate(-90deg) translateX(-.5rem);
}
<div class="main-grid">
<div class="container">
<div role="button" class="close-btn" aria-pressed="false" data-close-category-btn></div>
<img src="./assets/coffee-table.webp" alt="coffee table">
</div>
<div class="container">
<div role="button" class="close-btn" aria-pressed="false" data-close-category-btn></div>
<img src="./assets/coffee-table.webp" alt="coffee table">
</div>
<div class="container">
<div role="button" class="close-btn" aria-pressed="false" data-close-category-btn></div>
<img src="./assets/coffee-table.webp" alt="coffee table">
</div>
</div>

这么说吧…你在一个很短的代码中有很多混乱……我建议你尝试更简单的场景,以更好地集中一些概念。

我所说的混乱是使用在作用域之外定义的变量,并更好地理解事件冒泡的工作原理。

一旦大多数较小的问题得到解决,剩下的主要模糊的事实是,一旦关闭按钮被点击,停止点击事件的传播。问题是,由于关闭按钮嵌套在容器div中,并且都处理单击事件,因此关闭按钮触发的事件被传播到父类。为了快速解决这个问题,我检查了父单击处理程序,如果发起事件的元素符合预期,并在关闭按钮单击处理程序中强制stopPropagation。

演示非常非常浅…但它以某种方式显示了如何处理事件冒泡(如果你点击一个容器,它会变成红色和放大,如果你点击相应的关闭按钮,它会回到以前的状态):

const containers = document.querySelectorAll('.container');
let previouslyClickedContainer = '';
containers.forEach(container => {
container.addEventListener('click', () => {
if(
window.event.currentTarget.classList.contains("close-btn")
)return false;

const closeBtn = container.querySelector('.close-btn');
if(previouslyClickedContainer !== '') {
previouslyClickedContainer.classList.remove('enlarge');
}
container.classList.add('enlarge');
previouslyClickedContainer = container;
if(closeBtn.getAttribute('aria-pressed') === 'true') {
closeBtn.setAttribute('aria-pressed', 'false');
}
});

const closeBtn = container.querySelector('.close-btn');
closeBtn.addEventListener('click', () => {
const closeBtn = window.event.target;
const container = closeBtn.parentElement;
container.classList.remove('enlarge');
previouslyClickedContainer = '';
closeBtn.setAttribute('aria-pressed', 'true');

window.event.stopPropagation();
});
});
.main-grid { 
gap: 5rem; 
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
grid-auto-rows: minmax(350px, 1fr);
}
.container {
position: relative;
z-index: 99;
width: 100%;
height: 100%;
cursor: pointer;
transition: all 600ms ease-in-out;
}
/*
.container .close-btn {
position: absolute;
z-index: 101;
inset-inline-end: 0;
margin-block-start: 1.25rem;
margin-inline-end: .5rem;
opacity: 0;
transition: opacity 600ms ease-in-out;
border: solid 2px purple;
}
*/
.close-btn{
}
.close-btn::after{
color:black;
content: 'close';
}
.container img {
height: 100%;
}
/* class that is added and removed */
.enlarge {
z-index: 100;
width: 150%;
height: 150%;
box-shadow: 0px 0px 12px 0px hsl( var(--clr-dark) / .6 );
border: solid 2px red;
}
.enlarge .close-btn {
opacity: 1;
}
.close-btn {
position: relative;
width: 32px;
transform: rotate(45deg);
}
.close-btn,
.close-btn::after {
height: 2px;
background-color: white;
}
/*
.close-btn::after {
content: '';
position: absolute;
inset-inline: 0;
top: -.5rem;
transform: rotate(-90deg) translateX(-.5rem);
}
*/
<div class="main-grid">
<div class="container">
<div
role="button"
class="close-btn"
aria-pressed="false"
data-close-category-btn></div>
<img src="./assets/coffee-table.webp" alt="coffee table">
</div>
<div class="container">
<div
role="button"
class="close-btn"
aria-pressed="false"
data-close-category-btn=""></div>
<img src="./assets/coffee-table.webp" alt="coffee table" >
</div>
<div class="container">
<div
role="button"
class="close-btn"
aria-pressed="false"
data-close-category-btn=""></div>
<img src="./assets/coffee-table.webp" alt="coffee table">
</div>
</div>