在纯 JS 中单击添加/删除类

时间:2021-02-07 06:32:25

标签: javascript

我一直使用 jQuery,在那里很容易,但我决定改用纯 JS 并遇到了困难。 当我单击按钮时,我希望将 crossOut 类添加到具有 appOrd 类的 3 个元素中,并且按钮本身变为非活动状态(引导类 - disabled)。 而第二个按钮 Resume 则相反。 但是没有任何效果,请告诉我是什么问题?

P.S.我想在 const 中有错误,也许不能这样使用?

UPD-1。 Barmar 提出了一个错字,已更正。

UPD-2。有必要只将类添加到表的当前行。

const hasClass = document.querySelector('.appOrd').classList.contains('crossOut');

document.querySelector('.completeBtn').onclick=function(e) {
    e.preventDefault();

    if( !hasClass) {
        document.querySelector('.appOrd').classList.add('crossOut');
        document.querySelector('.resumeBtn').classList.remove('disabled');
        this.classList.add('disabled');
    }
}

document.querySelector('.resumeBtn').onclick=function(e) {
    e.preventDefault();

    if(hasClass) {
        document.querySelector('.appOrd').classList.remove('crossOut');
        document.querySelector('.completeBtn').classList.remove('disabled');
        this.classList.add('disabled');
    }
}
.crossOut{
  text-decoration: line-through;
}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<table class="table table-bordered">
      <thead>
        <tr class="text-center">
          <th scope="col">Name</th>
          <th scope="col">Phone number</th>
          <th scope="col">Application time</th>
          <th scope="col">Status</th>
        </tr>
      </thead>
      <tbody>
        <tr class="text-center">
          <td scope="row" class="appOrd">Name</td>
          <td class="appOrd">Phone number</td>
          <td class="appOrd">2021-02-07 08:40:48</td>
          <td>
            <a class="btn btn-success resumeBtn disabled" href="#">Resume</a>
            <a class="btn btn-danger completeBtn" href="#">Complete</a>
          </td>
        </tr>
      </tbody>
    </table>

3 个答案:

答案 0 :(得分:1)

您需要使用 querySelectorAll() 选择多个元素,然后更新所有元素的类。这可以通过 .forEach() 循环遍历它们来完成。

同样,使用 querySelectorAll()onclick 处理程序添加到每个按钮。

document.querySelectorAll('.completeBtn').forEach(el => el.onclick = function(e) {
  e.preventDefault();
  let row = this.closest("tr");
  row.querySelectorAll('.appOrd').forEach(el => el.classList.add('crossOut'));
  row.querySelector('.resumeBtn').classList.remove('disabled');
  this.classList.add('disabled');
});

document.querySelectorAll('.resumeBtn').forEach(el => el.onclick = function(e) {
  e.preventDefault();
  let row = this.closest("tr");
  row.querySelectorAll('.appOrd').forEach(el => el.classList.remove('crossOut'));
  row.querySelector('.completeBtn').classList.remove('disabled');
  this.classList.add('disabled');
});
.crossOut {
  text-decoration: line-through;
}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" />
<table class="table table-bordered">
  <thead>
    <tr class="text-center">
      <th scope="col">Name</th>
      <th scope="col">Phone number</th>
      <th scope="col">Application time</th>
      <th scope="col">Status</th>
    </tr>
  </thead>
  <tbody>
    <tr class="text-center">
      <td scope="row" class="appOrd">Name</td>
      <td class="appOrd">Phone number</td>
      <td class="appOrd">2021-02-07 08:40:48</td>
      <td>
        <a class="btn btn-success resumeBtn disabled" href="#">Resume</a>
        <a class="btn btn-danger completeBtn" href="#">Complete</a>
      </td>
    </tr>
    <tr class="text-center">
      <td scope="row" class="appOrd">Name 2</td>
      <td class="appOrd">Phone number 2</td>
      <td class="appOrd">2021-02-06 09:00:50</td>
      <td>
        <a class="btn btn-success resumeBtn disabled" href="#">Resume</a>
        <a class="btn btn-danger completeBtn" href="#">Complete</a>
      </td>
    </tr>
  </tbody>
</table>

答案 1 :(得分:1)

按钮用于它们所在的行,所以最好这样做

const resume = (src, enable) => {
  const tr = src.parentElement.parentElement;
  const nameElts = tr.querySelectorAll('.appOrd');

  if (enable) {
    nameElts.forEach(e => e.classList.remove('crossOut'));
  } else {
    nameElts.forEach(e => e.classList.add('crossOut'));
  }

  const completeBtn = tr.querySelector(".completeBtn");
  const resumeBtn = tr.querySelector(".resumeBtn");

  if (enable) {
    completeBtn.classList.remove('disabled');
    resumeBtn.classList.add('disabled');
  } else {
    resumeBtn.classList.remove('disabled');
    completeBtn.classList.add('disabled');
  }
}

document.querySelectorAll(".completeBtn").forEach(elt => {
  elt.onclick = () => {
    resume(event.target, false);
  }
});

document.querySelectorAll('.resumeBtn').forEach(elt => {
  elt.onclick = () => {
    resume(event.target, true);
  }
});
.crossOut {
  text-decoration: line-through;
}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" />
<table class="table table-bordered">
  <thead>
    <tr class="text-center">
      <th scope="col">Name</th>
      <th scope="col">Phone number</th>
      <th scope="col">Application time</th>
      <th scope="col">Status</th>
    </tr>
  </thead>
  <tbody>
    <tr class="text-center">
      <td scope="row" class="appOrd">Name</td>
      <td class="appOrd">Phone number</td>
      <td class="appOrd">2021-02-07 08:40:48</td>
      <td>
        <a class="btn btn-success resumeBtn disabled" href="#">Resume</a>
        <a class="btn btn-danger completeBtn" href="#">Complete</a>
      </td>
    </tr>
    <tr class="text-center">
      <td scope="row" class="appOrd">Name1</td>
      <td class="appOrd">Phone number1</td>
      <td class="appOrd">2021-02-08 08:40:48</td>
      <td>
        <a class="btn btn-success resumeBtn disabled" href="#">Resume</a>
        <a class="btn btn-danger completeBtn" href="#">Complete</a>
      </td>
    </tr>
  </tbody>
</table>

答案 2 :(得分:1)

我不确定这是不是最好的方法。

您可以查询表行 (tbody tr) 并通过查询 Complete and Resume 按钮和切换基于点击的类来添加处理程序。这样,您可以顺利处理行(tr)。

const rows = document.querySelectorAll('tbody tr')

rows.forEach(row => {
   const completeBtn = row.querySelector('.completeBtn');
   const resumeBtn = row.querySelector('.resumeBtn');
   const appOrds = row.querySelectorAll('.appOrd');
   
   completeBtn.addEventListener('click', function(e) {
     e.preventDefault();
     appOrds.forEach(el => el.classList.add('crossOut'));
     resumeBtn.classList.remove('disabled');
     this.classList.add('disabled');
   })

   resumeBtn.addEventListener('click', function(e) {
     e.preventDefault();
     appOrds.forEach(el => el.classList.remove('crossOut'));
     completeBtn.classList.remove('disabled');
     this.classList.add('disabled');
   })
})
.crossOut{
  text-decoration: line-through;
}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<table class="table table-bordered">
      <thead>
        <tr class="text-center">
          <th scope="col">Name</th>
          <th scope="col">Phone number</th>
          <th scope="col">Application time</th>
          <th scope="col">Status</th>
        </tr>
      </thead>
      <tbody>
        <tr class="text-center">
          <td scope="row" class="appOrd">Name</td>
          <td class="appOrd">Phone number</td>
          <td class="appOrd">2021-02-07 08:40:48</td>
          <td>
            <a class="btn btn-success resumeBtn disabled" href="#">Resume</a>
            <a class="btn btn-danger completeBtn" href="#">Complete</a>
          </td>
        </tr>
<tr class="text-center">
          <td scope="row" class="appOrd">Name</td>
          <td class="appOrd">Phone number</td>
          <td class="appOrd">2021-02-07 08:40:48</td>
          <td>
            <a class="btn btn-success resumeBtn disabled" href="#">Resume</a>
            <a class="btn btn-danger completeBtn" href="#">Complete</a>
          </td>
        </tr>
      </tbody>
    </table>