【问题标题】:Click a nav item, add a class, remove class from other nav items - vanilla JS单击一个导航项,添加一个类,从其他导航项中删除类 - vanilla JS
【发布时间】:2019-04-03 15:58:35
【问题描述】:

我可以在单击导航项时将is-active 类添加到导航项。但是,我想删除该类并在单击另一个导航项时将其添加到另一个导航项。

这是我目前正在使用的:

JS:

const links = document.querySelectorAll('a');

links.forEach(function(link, index){
  link.addEventListener('click', function() {
    if(this.classList.contains('is-active')) {
      this.classList.remove('is-active');
    } else {
      this.classList.add('is-active');
    }
  });
});

Here's a Codepen example.

此尝试添加类,但在单击另一个链接时不会将其删除。

如何删除课程?提前致谢。

【问题讨论】:

    标签: javascript html css class


    【解决方案1】:

    您只需遍历不是this 的链接:

    const links = document.querySelectorAll('a');
    
    links.forEach(function(link, index){
      link.addEventListener('click', function() {
        if(this.classList.contains('is-active')) {
          this.classList.remove('is-active');
        } else {
          this.classList.add('is-active');
          links.forEach(l => {                     // ***
              if (l !== this) {                    // ***
                  l.classList.remove('is-active'); // ***
              }                                    // ***
          });
        }
      });
    });
    

    (请参阅下面的for-of 版本。)

    或者,您可以只对 is-active 链接进行新查询:

    document.querySelectorAll('a').forEach(function(link, index){
      link.addEventListener('click', function() {
        if(this.classList.contains('is-active')) {
          this.classList.remove('is-active');
        } else {
          document.querySelectorAll('a.is-active').forEach(activeLink => { // ***
              activeLink.classList.remove('is-active');                    // ***
          });                                                              // ***
          this.classList.add('is-active');
        }
      });
    });
    

    或者如果你愿意,因为应该只有一个,querySelector

    document.querySelectorAll('a').forEach(function(link, index){
      link.addEventListener('click', function() {
        if(this.classList.contains('is-active')) {
          this.classList.remove('is-active');
        } else {
          const activeLink = document.querySelector('a.is-active'); // **
          if (activeLink) {                                         // **
              activeLink.classList.remove('is-active');             // **
          }                                                         // **
          this.classList.add('is-active');
        }
      });
    });
    

    旁注:来自querySelectorAllNodeList 在某些浏览器中没有forEach(它是最近才添加的)。请参阅this answer 了解如何在缺少它时添加它,以及(在 ES2015+ 平台上)如何确保它也是可迭代的(这也是它的本意)。


    如果你可以依赖可迭代性,这里有for-of 的版本:

    for-of版本的第一个例子:

    const links = document.querySelectorAll('a');
    for (const link of links) {
      link.addEventListener('click', function() {
        if(this.classList.contains('is-active')) {
          this.classList.remove('is-active');
        } else {
          this.classList.add('is-active');
          for (const l of links) {
              if (l !== this) {
                  l.classList.remove('is-active');
              }
          }
        }
      });
    }
    

    for-of第二个例子的版本:

    for (const link of document.querySelectorAll('a')) {
      link.addEventListener('click', function() {
        if(this.classList.contains('is-active')) {
          this.classList.remove('is-active');
        } else {
          for (const activeLink of document.querySelectorAll('a.is-active')) {
              activeLink.classList.remove('is-active');
          }
          this.classList.add('is-active');
        }
      });
    }
    

    第三个:

    for (const link of document.querySelectorAll('a')) {
      link.addEventListener('click', function() {
        if(this.classList.contains('is-active')) {
          this.classList.remove('is-active');
        } else {
          const activeLink = document.querySelector('a.is-active'); // **
          if (activeLink) {                                         // **
              activeLink.classList.remove('is-active');             // **
          }                                                         // **
          this.classList.add('is-active');
        }
      });
    }
    

    【讨论】:

      【解决方案2】:

      一个常见的要求 - 你可以这样做:

      • 使用spread syntax[...document.querySelectorAll('a')] 一样获得DOM 元素的可迭代表示

      • 使用forEach循环通过链接

      • 您可以使用 classList.toggle 函数来代替 if-else 条件

      请看下面的演示:

      // get an iterable representation using the spread syntax
      const elements = [...document.querySelectorAll('a')];
      
      elements.forEach(e => e.addEventListener('click', () => {
        // remove active class from all links
        elements.forEach(e => e.classList.remove('is-active'));
        // add active to the clicked link
        e.classList.toggle('is-active');
      }));
      .is-active {
        color: red;
      }
      <a href="#">Link 1</a>
      <a href="#">Link 2</a>
      <a href="#">Link 3</a>

      【讨论】:

        【解决方案3】:

        函数中的this指的是被点击的元素。您应该在每次单击时使用 forEach 隐藏所有元素。然后显示想要的一个

        const links = [...document.querySelectorAll('a')];
        
        links.forEach(function(link, index){
          link.addEventListener('click', function() {
            let temp = this.classList.contains('is-active')
            links.forEach(x => x.classList.remove('is-active'))
            if(!temp) {
              this.classList.add('is-active');
            } 
          });
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-02-06
          • 2012-11-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多