通过按钮列表添加和删除 Class

Add and Remove a Class through a list of Buttons

我有一个按钮列表。

我需要为它们中的每一个添加一个 clickEvent,当点击它时需要检查是否有另一个带有 class(btnActive) 的按钮,将其删除并将 class 添加到被点击的按钮。

document.querySelectorAll('.btn').forEach(function(el) {
  el.addEventListener('click', function(e) {
    let i = 0;
    for (i = 0; i < btnAll.length; i++) {
      if (i.classList.contains('btnActive')) {
        i.classList.remove('btnActive');
      }
    }
    el.classList.add('btnActive');
  });
});
<div class="btnContainer">

  <div class="btn">
    <span class="btnActive">
          0
        </span>
  </div>

  <div class="btn">
    <span>
         1
        </span>
  </div>

  <div class="btn">
    <span>
          2
        </span>
  </div>

  <div class="btn">
    <span>
          3
        </span>

  </div>
</div>

我有那个小 JS 块,但我似乎无法让它工作

您有 2 个问题:

  • 您在 for 循环中引用了 btnAll.length,但未定义 btnAll。您需要定义它并为其分配按钮数组。

  • 您实际上并没有在 if 语句中操作 HTML 按钮。相反,您试图使用 i(index) 这是一个数字。要引用实际的 HTML 按钮,您需要执行 btnAll[i].

也就是说,您的实际问题可能不是读取控制台中抛出的错误。

const btnAll = document.querySelectorAll('.btn')

btnAll.forEach(function(el) {
    el.addEventListener('click', function (e) {
        let i = 0;
        for(i = 0; i < btnAll.length; i++){
            const btn = btnAll[i]

            if(btn.classList.contains('btnActive')){
              btn.classList.remove('btnActive');
            }
        }

        el.classList.add('btnActive');
    });
});
.btnActive {
  color: red;
}
<div class="btnContainer">

  <div class="btn">
    <span class="btnActive">
      0
    </span>
  </div>

  <div class="btn">
    <span>
     1
    </span>
  </div>

  <div class="btn">
    <span>
      2
    </span>
  </div>

  <div class="btn">
    <span>
      3
    </span>

  </div>
</div>

您的代码包含大量语法错误:

  1. btnAll 未定义。
  2. 您正试图通过 i 直接访问 dom 元素。请改用 btnAll[i]

document.querySelectorAll('.btn').forEach(function(el) {
  el.addEventListener('click', function(e) {

var btnAll = document.querySelectorAll('.btn');
let i = 0;
    for (i = 0; i < btnAll.length; i++) {
      if (btnAll[i].classList.contains('btnActive')) {
        btnAll[i].classList.remove('btnActive');
      }
    }
    el.classList.add('btnActive');
  });
});
.btn.btnActive
{
  font-weight:900;
  color:red;
}
<div class="btnContainer">

  <div class="btn">
    <span class="btnActive">
          0
        </span>
  </div>

  <div class="btn">
    <span>
         1
        </span>
  </div>

  <div class="btn">
    <span>
          2
        </span>
  </div>

  <div class="btn">
    <span>
          3
        </span>

  </div>
</div>

使 .btnActive class 在与 .btn 相同的 div 上工作。然后循环遍历 btnAll els 以删除 class,然后再将其添加到单击的元素:

let btnAll = document.querySelectorAll('.btn');

document.querySelectorAll('.btn').forEach(function(el1) {
  el1.addEventListener('click', function(e) {
    btnAll.forEach(function(el2) {
      el2.classList.remove('btnActive');
    });
    el1.classList.add('btnActive');
  });
});
.btn {
  padding: 10px 20px;
  background: lightblue;
  text-align: center;
  display: inline-block;
}

.btn.btnActive {
  background: orangered;
  color: white;
}
<div class="btnContainer">
  <div class="btn">0</div>
  <div class="btn">1</div>
  <div class="btn">2</div>
  <div class="btn">3</div>
</div>

由于其他答案已经涵盖了为什么您的代码不起作用,这里有一个示例,您将 一个 事件侦听器附加到容器并捕获从另一个冒泡的事件元素(参见:event propagation)。它使代码更实用。

// Get the container and the buttons
const container = document.querySelector('.btnContainer');
const buttons = document.querySelectorAll('.btn');

// Add a click listener to the container
container.addEventListener('click', handleClick, false);

function handleClick(e) {
  const { target } = e;

  // If a button has been clicked
  if (target.classList.contains('btn')) {

    // Clear any active buttons 
    buttons.forEach(button => button.classList.remove('btnActive'));

    // Make the clicked button active
    target.classList.add('btnActive');
  }
}
.btnActive {
  background-color: red;
}
<div class="btnContainer">
  <button class="btn btnActive">0</button>
  <button class="btn">1</button>
  <button class="btn">2</button>
  <button class="btn">3</button>
</div>