问题描述
我有一个我想要的包装容器,所以当我点击名称时,每条信息只为该包装显示,当我点击/关闭“x”按钮时,它只会为该按钮删除它。
>使用 forEach()
方法显示和删除所有内部容器,除了那些被点击的容器。
我认为使用 this
关键字可能可行,但我无法让它发挥作用。
我是 Javascript 的新手,因此我们将不胜感激。
代码笔:https://codepen.io/anna_paul/pen/JjWPLjx
window.addEventListener('DOMContentLoaded',function() {
let name = document.querySelectorAll('.name')
let close = document.querySelectorAll('.close')
let innerText = document.querySelectorAll('.inner-text')
// ----- show text
name.forEach(function(item){
item.addEventListener('click',function(){
innerText.forEach(function(inner){
inner.classList.add('active')
})
},false)
})
// ---- hide text
close.forEach(function(item){
item.addEventListener('click',function(){
innerText.forEach(function(inner){
inner.classList.remove('active')
})
},false)
})
}) // DomContentLoaded
* {position: relative; Box-sizing: border-Box;}
body {
margin: 0;
height: 100vh;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.wrapper {
width: 10rem;
background: #fafafa;
padding: 1rem;
margin: 1rem;
}
.inner-text {
background: red;
display:none;
}
.inner-text.active {
display: block
}
.close {
position: absolute;
top: -5rem;
right: 0rem;
padding: .5rem;
background: white;
z-index: 2;
}
.name {
background: yellow;
padding: 1rem;
cursor: pointer;
}
<div class="wrapper">
<p class="name">Name</p>
<div>Other content</div>
<div class="inner-text">
<div class="close">x</div>
<ul>
<li>INFO</li>
<li>INFO</li>
<li>INFO</li>
<li>INFO</li>
<li>INFO</li>
</ul>
</div>
</div>
<div class="wrapper">
<p class="name">Name</p>
<div>Other content</div>
<div class="inner-text">
<div class="close">x</div>
<ul>
<li>INFO</li>
<li>INFO</li>
<li>INFO</li>
<li>INFO</li>
<li>INFO</li>
</ul>
</div>
</div>
解决方法
您几乎已经确定了问题中的问题,即您正在遍历事件处理程序中的所有面板并向所有面板添加/删除类。相反,您可以使用“事件委托”,即在所有面板的共同祖先处设置一个事件处理程序,然后让事件“冒泡”到该祖先并在那里处理。此外,由于 show 和 hide 的代码非常相似,您可以只为两者使用一个函数。
最后,innerText
不是一个好的变量名称,因为 innerText
实际上是一个 DOM 元素属性名称。
// If you place the script that holds this code just before the
// closing BODY tag,you won't need to set up a DOMContentLoaded
// event.
document.querySelector(".masterWrapper").addEventListener("click",function(event){
// Check to see if the event originated at an element
// we care about handling
// Get a reference to the <div class="wrapper"> ancestor of the clicked element
// and then find the <div class="inner-text"> descedant within it.
const inner_text = event.target.closest(".wrapper").querySelector(".inner-text");
// When Name is clicked
if(event.target.classList.contains("name")){
// If the panel is not already showing its content:
if(!inner_text.classList.contains("active")){
inner_text.classList.add("active");
}
}
// When the X is clicked
if(event.target.classList.contains("close")){
event.target.parentElement.classList.remove("active");
}
});
* {position: relative; box-sizing: border-box;}
body {
margin: 0;
height: 100vh;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.wrapper {
width: 10rem;
background: #fafafa;
padding: 1rem;
margin: 1rem;
}
.inner-text {
background: red;
display:none;
}
.inner-text.active {
display: block
}
.close {
position: absolute;
top: -5rem;
right: 0rem;
padding: .5rem;
background: white;
z-index: 2;
}
.name {
background: yellow;
padding: 1rem;
cursor: pointer;
}
<div class="masterWrapper">
<div class="wrapper">
<p class="name">Name</p>
<div>Other content</div>
<div class="inner-text">
<div class="close">x</div>
<ul>
<li>INFO</li>
<li>INFO</li>
<li>INFO</li>
<li>INFO</li>
<li>INFO</li>
</ul>
</div>
</div>
<div class="wrapper">
<p class="name">Name</p>
<div>Other content</div>
<div class="inner-text">
<div class="close">x</div>
<ul>
<li>INFO</li>
<li>INFO</li>
<li>INFO</li>
<li>INFO</li>
<li>INFO</li>
</ul>
</div>
</div>
</div>