【问题标题】:Target all elements in a list excepted clicked定位列表中的所有元素,但单击除外
【发布时间】:2021-01-25 20:38:17
【问题描述】:

我一直在玩 jQuery,但我终于尝试学习干净的 Vanilla JS。

我有一个元素列表:

    <div id="seriesList" class="seriesList rollable">

            <div class="seriesLink" series="7">
                <a href="#carrow-road"><h3 class="name">Carrow Road</h3><p class="location">Norwich</p></a>
            </div>

            <div class="seriesLink" series="6">
                <a href="#white-lane"><h3 class="name">White Heart Lane</h3><p class="location">London</p></a>
            </div>

            <div class="seriesLink" series="5">
                <a href="#parc-des-princes"><h3 class="name">Parc des Princes</h3><p class="location">Paris</p></a>
            </div>
</div

单击其中一个 .seriesLink 后,我正在切换一系列 GSAP 动画。我要实现的第一个目标是使单击的每个元素都消失。 即:我点击#carrow-road — #white-lane 和 #parc-des-princes 会消失。

我有这个:

document.querySelectorAll(".seriesLink").forEach(item => {
  item.addEventListener('click', event => {

// ForEach.Not ?

    document.getElementById("seriesList").classList.toggle("rollable");
    document.getElementById("home").classList.add("scrollable");
    document.getElementById("rightPanel").classList.remove("scrollable");
    tlOpenSeries.play();
  })
})

Javascript 中的“类”系统让我迷失了方向,因为我似乎无法成功定位我的元素。

我找不到“重现”each.not jquery 提供的方法。任何想法?我是否应该首先向单击的元素添加一个类,然后然后定位所有没有这个“活动”类的元素?有捷径吗?

非常感谢

【问题讨论】:

  • item.addEventListener('click', event => 匿名箭头函数使得很难知道点击了哪个元素。没有'this'。

标签: javascript each


【解决方案1】:

你可以使用filter:

const seriesLinks = document.querySelectorAll(".seriesLink");

seriesLinks.forEach(item => {
   item.addEventListener('click', event => {
    
      seriesLinks
        .filter(i => i != item)
        .forEach(i => // your logic... //);

//... rest of your code ... //
   })
})

但是我认为一个好的做法是将代码拆分为简单的小函数,例如hideAllExceptCurrent (allElemArray, currentElem)hideAllToggleCurrent (allElemArray, currentElem)

【讨论】:

  • 为什么事先将 seriesLink 设置为 const 更好?性能方面还是只是为了让阅读更容易?
  • 让阅读更轻松。性能不足在这里可以忽略不计
  • 我对上述解决方案有一些关于效率的担忧:在包装元素上维护 single 事件侦听器比在每个子节点上侦听更安全、更容易; .querySelectorAll() 是一个很好的高级查询工具.getElementsByClassName() 在这种特殊情况下会表现得更好;上面的代码在所有链接中不必要地循环不必要两次(.filter().forEach()),单次循环.forEach()有条件地应用必要的逻辑,似乎更多合理。
【解决方案2】:

要在 vanilla JS 中实现这一点,您必须遍历元素并检查当前元素是否不是被点击的元素。

演示:

var divs = document.querySelectorAll(".seriesLink");
divs.forEach(item => {
  item.addEventListener('click', event => {

    for(var i = 0; i < divs.length; i++){
      if(event.currentTarget != divs[i]){ // check here
        divs[i].style.display = "none";
      }
    }
    
    //.......
    //.......
  });
});
<div id="seriesList" class="seriesList rollable">
  <div class="seriesLink" series="7">
    <a href="#carrow-road"><h3 class="name">Carrow Road</h3><p class="location">Norwich</p></a>
  </div>

  <div class="seriesLink" series="6">
    <a href="#white-lane"><h3 class="name">White Heart Lane</h3><p class="location">London</p></a>
  </div>

  <div class="seriesLink" series="5">
    <a href="#parc-des-princes"><h3 class="name">Parc des Princes</h3><p class="location">Paris</p></a>
  </div>
</div>

【讨论】:

  • @JoePythonKing,首先,我更喜欢坚持使用 OP 的代码,其次,因为箭头函数没有自己的 this 来识别我使用的点击块currentTarget: )
猜你喜欢
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-21
  • 1970-01-01
  • 2022-07-06
  • 1970-01-01
相关资源
最近更新 更多