【问题标题】:Javascript - cannot change active elementJavascript - 无法更改活动元素
【发布时间】:2021-05-26 03:50:45
【问题描述】:

我对前端开发中的 JavaScript 完全陌生,我有一个非常基本的问题,我似乎无法弄清楚...我正在制作一个表格导航栏,其中突出显示了活动元素。

我知道还有其他方法可以达到预期的效果,但我的脚本有什么问题?

function navTabsClick(child) {
    getElementsByClassName("active")[0].classList.remove("active");
    child.getElementsByTagName("li")[0].className = "active";
}
ul{
  display: flex;
  list-style-type: none;
}
a{
  text-decoration: none;
}
a:link, a:visited{
  color: black;
}
a:hover{
  cursor: pointer;
}
li{
  margin: 0;
  padding: 10px 30px;
  background-color: lightgray;
}
li:hover{
  background-color: darkgray;
}
li.active{
  background-color: red;
}
<nav>
  <ul>
    <a onclick="navTabsClick(this)">
      <li class="active">1</li>
    </a>
    <a onclick="navTabsClick(this)">
      <li>2</li>
    </a>
    <a onclick="navTabsClick(this)">
      <li>3</li>
    </a>
  </ul>
</nav>

如果我删除我的 JavaScript 函数的第一行,我可以让其他选项卡突出显示,但我得到以下错误:

Uncaught ReferenceError: getElementsByClassName is not defined

我错过了什么?

另外,作为第二个问题,还有比这更好的处理导航栏 JavaScript 的方法吗?

【问题讨论】:

  • 我是document.getElementsByClassName
  • 试试document.getElementsByClassName()
  • 试试document.getElementByClassName
  • 作为新手,请接受这个建议,您将在网络上看到的大多数示例都不是由了解他们所使用的代码的人创建的。在很多很多情况下,他们复制了其他人似乎可以工作的代码。如果你遵循这种行为,你就会养成一些非常坏的习惯。一开始就不要使用这样的代码:getElementsByClassName("active")[0]
  • 只需阅读我分享的链接即可。它说明document.querySelector() 是更好的解决方案。

标签: javascript html css


【解决方案1】:

试试document.getElementByClassName

function navTabsClick(child) {
    document.getElementsByClassName("active")[0].classList.remove("active");
    child.getElementsByTagName("li")[0].className = "active";
}
ul{
  display: flex;
  list-style-type: none;
}
a{
  text-decoration: none;
}
a:link, a:visited{
  color: black;
}
a:hover{
  cursor: pointer;
}
li{
  margin: 0;
  padding: 10px 30px;
  background-color: lightgray;
}
li:hover{
  background-color: darkgray;
}
li.active{
  background-color: red;
}
<nav>
  <ul>
    <a onclick="navTabsClick(this)">
      <li class="active">1</li>
    </a>
    <a onclick="navTabsClick(this)">
      <li>2</li>
    </a>
    <a onclick="navTabsClick(this)">
      <li>3</li>
    </a>
  </ul>
</nav>

【讨论】:

    【解决方案2】:

    函数是document.getElementsByClassName

    function navTabsClick(child) {
      document.getElementsByClassName("active")[0].classList.remove("active");
      child.getElementsByTagName("li")[0].className = "active";
    }
    ul {
      display: flex;
      list-style-type: none;
    }
    
    a {
      text-decoration: none;
    }
    
    a:link,
    a:visited {
      color: black;
    }
    
    a:hover {
      cursor: pointer;
    }
    
    li {
      margin: 0;
      padding: 10px 30px;
      background-color: lightgray;
    }
    
    li:hover {
      background-color: darkgray;
    }
    
    li.active {
      background-color: red;
    }
    <nav>
      <ul>
        <a onclick="navTabsClick(this)">
          <li class="active">1</li>
        </a>
        <a onclick="navTabsClick(this)">
          <li>2</li>
        </a>
        <a onclick="navTabsClick(this)">
          <li>3</li>
        </a>
      </ul>
    </nav>

    【讨论】:

      【解决方案3】:

      您在getElementsByClassName 之前缺少document

      【讨论】:

        【解决方案4】:

        其他人指出必须在元素上调用getElementsByClassName,但这并不能解决您问题的第二部分。

        还有比这更好的处理导航栏 JavaScript 的方法吗?

        现在,您正在为每个菜单项设置一个事件侦听器,这是不必要的。 click 事件公开了在 target 属性中单击的元素。您可以在菜单本身上设置单个事件侦听器,并使用此属性来确定单击了哪个项目。

        这还允许您删除菜单项周围的a 标签。 我认为这些会导致屏幕阅读器出现问题。 编辑:正如 Scott 所指出的, click 事件原本可以直接设置在 li 标签上。

        这是一个修改后的示例,菜单只有一个事件。

        function navClicked(nav, item) {
          
          /* Do not attempt to set the nav
             menu itself to the active item */
          if (nav === item) return;
          
          /* Do not change the active item if the
             item that was clicked is already active */
          if (item.classList.contains("active")) return;
          
          /* Remove the class from all nav items */
          Array.from(nav.children)
               .forEach(child => child.classList.remove("active"));
          
          /* Add the class to the item that was clicked */
          item.classList.add("active");
        }
        ul {
          display: flex;
          list-style-type: none;
        }
        
        a {
          text-decoration: none;
        }
        
        a:link,
        a:visited {
          color: black;
        }
        
        a:hover {
          cursor: pointer;
        }
        
        li {
          margin: 0;
          padding: 10px 30px;
          background-color: lightgray;
        }
        
        li:hover {
          background-color: darkgray;
        }
        
        li.active {
          background-color: red;
        }
        <nav>
          <ul onclick="navClicked(this, event.target)"> <!-- 'this' is the ul element, 'event.target' is the li element that was clicked -->
            <li class="active">1</li>
            <li>2</li>
            <li>3</li>
          </ul>
        </nav>

        【讨论】:

        • 这还允许您删除菜单项周围的 a 标签。 虽然我同意您关于事件委托的建议,但我想指出 @987654331 @ 元素永远不需要在那里,因为您可以在任何可见的 DOM 元素上添加 click 事件处理程序,例如 li 元素本身。
        猜你喜欢
        • 2020-01-10
        • 2014-12-23
        • 2015-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-28
        相关资源
        最近更新 更多