【问题标题】:Toggle classes with getElementsByClassName inside a foreach loop with Javascript使用 Javascript 在 foreach 循环中使用 getElementsByClassName 切换类
【发布时间】:2021-09-25 11:48:58
【问题描述】:

我无法让这个切换类脚本在所有项目 div 中工作。

它的设置是,当单击父元素时,两个子元素都会切换类.hide,它的功能更像是交换。

注意到这个使用 Jquery Toggle classes inside a foreach loop 的类似帖子,我采取了不同的方法,因为在这种情况下有多个类需要更改。

我使用getElementsByClassName 并将NodeList 中的元素定义为[0]。这适用于第一个项目 div 和更改为 [1] 的第二个。

但是,我一直坚持如何在所有后续项目 div 中同时进行这项工作。这是用循环完成的吗?还是使用变量?还是使用this 关键字?

我正在使用 Kirby CMS 生成内容部分,因此项目 div 模板在 foreach 循环内。

document.getElementsByClassName('read-more-div')[0].addEventListener('click', function() {

  document.getElementsByClassName('read-more-btn1')[0].classList.toggle('hide');
  document.getElementsByClassName('read-more-btn2')[0].classList.toggle('hide');

  return false

})
body {
  background-color: #000000;
  color: #ffffff;
}

p,
button {
  background-color: #000000;
  color: #ffffff;
  border: none;
  padding: 0;
  margin: 0;
}

.read-more-btn1 {
  color: #888888;
  cursor: s-resize;
}

.read-more-btn2 {
  cursor: n-resize;
}

.read-more-btn1:hover {
  color: #ffffff;
}

.hide {
  display: none;
}
<div>Project A

  <div class="read-more-div">

    <button class="read-more-btn1">Read more...</button>
    <p class="read-more-btn2 hide">Toggle this project text</p>

  </div>

</div>

<div>Project B

  <div class="read-more-div">

    <button class="read-more-btn1">Read more...</button>
    <p class="read-more-btn2 hide">Toggle this project text</p>

  </div>

</div>

<div>Project C

  <div class="read-more-div">

    <button class="read-more-btn1">Read more...</button>
    <p class="read-more-btn2 hide">Toggle this project text</p>

  </div>

</div>

【问题讨论】:

  • 使用event delegation而不是分配多个事件监听器 — 它更易于维护,并且适用于动态添加的元素。例如,使用event argumenttarget。见the tag infoWhat is DOM Event delegation?
  • 类似addEventListener("click", ({ target }) =&gt; { if(target.closest(".read-more-div")){ target.querySelectorAll(".read-more-btn1, .read-more-btn2").forEach(({ classList }) =&gt; classList.toggle("hide")); } });
  • 请注意,return false; 可以删除。它什么也没做。
  • 很高兴知道作为另一种方法!我将不得不阅读看起来更复杂的事件委托。我还处于学习js的早期阶段
  • sn-p 似乎不起作用,我还不知道为什么

标签: javascript html css getelementsbyclassname nodelist


【解决方案1】:

有很多方法可以做到这一点。确保将事件侦听器添加到所有 div 而不仅仅是第一个。 查看您当前的代码,您可以遵循这种方法。

this inside 事件监听器属于触发事件的元素。因此,当我们执行this.getElementsByClassName 时,我们只在该特定元素内查询类。

getElementsByClassName 不返回数组。它返回一个类数组的集合。要在类似数组的对象上使用forEach(),需要将其转换为数组。使用...(扩展)运算符将集合转换为数组。

[...document.getElementsByClassName('read-more-div')].forEach(x => x.addEventListener('click', function() {

  this.getElementsByClassName('read-more-btn1')[0].classList.toggle('hide');
  this.getElementsByClassName('read-more-btn2')[0].classList.toggle('hide');

  return false

}));
body {
  background-color: #000000;
  color: #ffffff;
}

p,
button {
  background-color: #000000;
  color: #ffffff;
  border: none;
  padding: 0;
  margin: 0;
}

.read-more-btn1 {
  color: #888888;
  cursor: s-resize;
}

.read-more-btn2 {
  cursor: n-resize;
}

.read-more-btn1:hover {
  color: #ffffff;
}

.hide {
  display: none;
}
<div>Project A

  <div class="read-more-div">

    <button class="read-more-btn1">Read more...</button>
    <p class="read-more-btn2 hide">Toggle this project text</p>

  </div>

</div>

<div>Project B

  <div class="read-more-div">

    <button class="read-more-btn1">Read more...</button>
    <p class="read-more-btn2 hide">Toggle this project text</p>

  </div>

</div>

<div>Project C

  <div class="read-more-div">

    <button class="read-more-btn1">Read more...</button>
    <p class="read-more-btn2 hide">Toggle this project text</p>

  </div>

</div>

【讨论】:

  • 谢谢!这行得通,感谢您的解释。可能需要了解这个理论,但很高兴知道它并不太遥远。调试此类问题的任何提示?
猜你喜欢
  • 1970-01-01
  • 2014-10-04
  • 2015-07-04
  • 1970-01-01
  • 2020-07-01
  • 1970-01-01
  • 2019-01-05
  • 2020-06-17
  • 2021-01-28
相关资源
最近更新 更多