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

Click Event Shows And Removes All Overlays Instead Of Individually - JavaScript

我有一个我想要的包装器容器,所以当我单击名称时,每条信息都只显示该包装器,当我 click/close '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>

您几乎已经确定了您问题中的问题,即您正在遍历事件处理程序中的所有面板,并 adding/removing 类 遍历所有面板。相反,您可以使用“事件委托”,在所有面板的共同祖先处只设置一个事件处理程序,让事件“冒泡”到该祖先并在那里进行处理。另外,因为显示和隐藏的代码非常相似,所以你可以只用一个函数来实现两者。

最后,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>