【问题标题】:Javascript add class to multiple elements except oneJavascript将类添加到除一个之外的多个元素
【发布时间】:2021-12-15 08:49:27
【问题描述】:

从 JavaScript 开始,我编写了一个小脚本,在单击时向元素添加一个类,然后当且仅当另一个元素被单击时才删除该类。

我试图尊重 DRY,所以我知道我应该写一个函数来避免重复代码,例如:

function ToggleClass(element) {
  if (FacebookConst.classList.contains("link-ranking-active") || GoogleConst.classList.contains("link-ranking-active") || ComparisonConst.classList.contains("link-ranking-active") {
  //remove "link-ranking-active" class to all constants **BUT** of element    
  };  
};

但我不知道语法。

这是我的代码:

const GoogleConst = document.getElementById('Google');
const FacebookConst = document.getElementById('Facebook');
const ComparisonConst = document.getElementById('Comparison');

const Page = document.getElementById("result");

GoogleConst.addEventListener("click", e => {
    GoogleConst.classList.add("link-ranking-active");
    if (FacebookConst.classList.contains("link-ranking-active") || ComparisonConst.classList.contains("link-ranking-active")) {
      FacebookConst.classList.remove("link-ranking-active");
      ComparisonConst.classList.remove("link-ranking-active");
    };
});

FacebookConst.addEventListener("click", e => {
    FacebookConst.classList.add("link-ranking-active");
    if (GoogleConst.classList.contains("link-ranking-active") || ComparisonConst.classList.contains("link-ranking-active")) {
      GoogleConst.classList.remove("link-ranking-active");
      ComparisonConst.classList.remove("link-ranking-active");
    };
});

ComparisonConst.addEventListener("click", e => {
    ComparisonConst.classList.add("link-ranking-active");
    if (FacebookConst.classList.contains("link-ranking-active") || GoogleConst.classList.contains("link-ranking-active")) {
      FacebookConst.classList.remove("link-ranking-active");
      GoogleConst.classList.remove("link-ranking-active");
    };
});
.link-ranking-active{
  box-sizing: border-box;
  position:relative;
  padding: 0.3em;
  height: 100%;
  width: 100%;
  border-radius: 0.3em;
  border: 0.15em solid #48ffd5;
}
<div class="page">
    <div class="ranking" id="ranking">
      <ul class="ul-menu">
        <li class="li-menu"><a class="link-ranking" id="Google" href="#key">Google</a></li>
        <li class="li-menu"><a class="link-ranking" id="Facebook" href="#key">Facebook</a></li>
        <li class="li-menu"><a class="link-ranking" id="Comparison" href="#key">Comparison</a></li>
      </ul>
    </div>
</div>

【问题讨论】:

    标签: javascript html css function class


    【解决方案1】:

    经典...

    要知道的东西=
    1- classList.toggle() 返回一个布尔值
    2- classList.toggle( CLASSname, Force ) 使用 force 设置类

    document
     .querySelectorAll('a.link-ranking')
     .forEach((aLink,_,arr)=>{
      aLink.onclick =()=>{
        if ( aLink.classList.toggle('link-ranking-active')) {
          arr.forEach(a=>a.classList.toggle('link-ranking-active',aLink===a))
        }}
      })
    .link-ranking-active {
      box-sizing    : border-box;
      position      : relative;
      padding       : 0.3em;
      height        : 100%;
      width         : 100%;
      border-radius : 0.3em;
      border        : 0.15em solid #48ffd5;
      }
    ul.ul-menu li {
      margin : 1em ;
      }
    <div class="page">
      <div class="ranking" id="ranking">
        <ul class="ul-menu">
          <li class="li-menu"><a class="link-ranking" id="Google" href="#key">Google</a></li>
          <li class="li-menu"><a class="link-ranking" id="Facebook" href="#key">Facebook</a></li>
          <li class="li-menu"><a class="link-ranking" id="Comparison" href="#key">Comparison</a></li>
        </ul>
      </div>
    </div>

    如果您不想在第二次单击时删除该类:

    document.querySelectorAll('a.link-ranking').forEach((aLink,_,arr)=>{
      aLink.onclick =()=>{
        arr.forEach(a=>a.classList.toggle('link-ranking-active',aLink===a))
      }})
    .link-ranking-active {
      box-sizing    : border-box;
      position      : relative;
      padding       : 0.3em;
      height        : 100%;
      width         : 100%;
      border-radius : 0.3em;
      border        : 0.15em solid #48ffd5;
      }
    ul.ul-menu li {
      margin : 1em ;
      }
    <div class="page">
      <div class="ranking" id="ranking">
        <ul class="ul-menu">
          <li class="li-menu"><a class="link-ranking" id="Google" href="#key">Google</a></li>
          <li class="li-menu"><a class="link-ranking" id="Facebook" href="#key">Facebook</a></li>
          <li class="li-menu"><a class="link-ranking" id="Comparison" href="#key">Comparison</a></li>
        </ul>
      </div>
    </div>

    【讨论】:

      【解决方案2】:

      这里使用的技术称为Event Delegation。以下是它的工作原理:

      1. 在容器上设置单个事件处理程序
      2. 如果不是锚标记,则忽略该事件
      3. 否则,从所有锚点中清除类名
      4. 最后,将类名应用到事件的目标(被点击的那个)。

      const container = document.querySelector('.ul-menu');
      const anchors = document.querySelectorAll('.ul-menu li a');
      
      container.addEventListener('click', (e) => {
        if (e.target.nodeName !== "A") return;
        anchors.forEach(anchor => {
          anchor.classList.remove('link-ranking-active');
        });
        e.target.classList.add('link-ranking-active');
      
      });
      .link-ranking-active {
        box-sizing: border-box;
        position: relative;
        padding: 0.3em;
        height: 100%;
        width: 100%;
        border-radius: 0.3em;
        border: 0.15em solid #48ffd5;
      }
      <div class="page">
        <div class="ranking" id="ranking">
          <ul class="ul-menu">
            <li class="li-menu"><a class="link-ranking" id="Google" href="#key">Google</a></li>
            <li class="li-menu"><a class="link-ranking" id="Facebook" href="#key">Facebook</a></li>
            <li class="li-menu"><a class="link-ranking" id="Comparison" href="#key">Comparison</a></li>
          </ul>
        </div>
      </div>

      【讨论】:

      • 感谢您的回答。但是,为了学习,我不确定这条线是做什么的:if (e.target.nodeName !== "A") return; anchors.forEach(anchor =&gt;
      • 该代码指的是我回答中的第 2 步。如果节点(HTML 元素)不是并且 Anchor (&lt;a&gt;) 则只需返回(退出)函数什么都不做。与为每个锚标记添加事件处理程序的其他答案不同,只需要一个。事件冒泡是在您的情况下使用的工具。它允许单个事件处理程序在这种情况下使用单个函数处理“单击”事件。短而甜。如果您觉得它有帮助,您可以随时将您接受的答案切换到此答案。我在答案中链接的文章为您提供了很多解释。玩得开心!
      【解决方案3】:

      很高兴你意识到你应该清理这个。一旦你看到它,代码应该是相当不言自明的。

      const elements = ['Google', 'Facebook', 'Comparison'].map(id => document.getElementById(id))
      
      const eventHandler = (e => {
        elements.map(element => element.classList.remove("link-ranking-active"))
        e.target.classList.add("link-ranking-active")
      })
      
      elements.forEach(element => element.addEventListener("click", eventHandler))
      .link-ranking-active {
        box-sizing: border-box;
        position: relative;
        padding: 0.3em;
        height: 100%;
        width: 100%;
        border-radius: 0.3em;
        border: 0.15em solid #48ffd5;
      }
      <div class="page">
        <div class="ranking" id="ranking">
          <ul class="ul-menu">
            <li class="li-menu"><a class="link-ranking" id="Google" href="#key">Google</a></li>
            <li class="li-menu"><a class="link-ranking" id="Facebook" href="#key">Facebook</a></li>
            <li class="li-menu"><a class="link-ranking" id="Comparison" href="#key">Comparison</a></li>
          </ul>
        </div>
      </div>

      【讨论】:

        猜你喜欢
        • 2013-10-09
        • 2014-06-27
        • 1970-01-01
        • 2012-09-20
        • 1970-01-01
        • 2010-12-31
        • 1970-01-01
        • 2016-12-24
        • 2018-05-13
        相关资源
        最近更新 更多