单击事件显示和删除所有覆盖而不是单独 - JavaScript

问题描述

我有一个我想要的包装容器,所以当我点击名称时,每条信息只为该包装显示,当我点击/关闭“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>