如何改进我的 JavaScript 以打开我的手风琴菜单

问题描述 投票:0回答:1

我做错了什么?知道如何使这个手风琴菜单起作用吗?

我一直在试图找出为什么我的前端挑战手风琴菜单不起作用。目前抛出以下错误:

未捕获类型错误:无法读取 HTMLButtonElement 处未定义的属性(读取“切换”)。

此错误来自 Google 开发工具。我的

active
类是在我的 css 文件中定义的。当我的按钮处于活动状态时,我试图让它在两个类之间切换,但我根本无法激活它或切换它。

有人可以帮助我了解发生了什么事吗?

这些是我的代码片段。

HTML

<div class="accordion">
  <button class="accordion_btn">
  What is Frontend Mentor, and how will it help me?
  </button>
  <div class="panel">
    <p> Frontend Mentor offers...</p>
  </div>
</div>

<div class="accordion">
  <button class="accordion_btn">
    Is Frontend Mentor free?
  </button>
  <div class="panel">
    <p>Yes, Frontend Mentor...</p>
  </div>
</div>

<div class="accordion">
  <button class="accordion_btn">
    Can I use Frontend Mentor projects in my portfolio?
  </button>
  <div class="panel">
    <p>Yes...</p>
  </div>
</div>

<div class="accordion">
  <button class="accordion_btn">
    How can I get help if I'm stuck on a Frontend Mentor challenge?
  </button>
  <div class="panel">
    <p>The best place to...</p>
  </div>
</div>
</div>

CSS

.accordion_btn {
    width: 100%;
    background-color: hsl(0, 0%, 100%);
    text-align: left; 
    border: none;
    outline: none;
    margin: 20px 0;
    transition: 0.4s; 
}

.accordion_btn:hover {
    background-color: hsl(276, 51%, 90%);
}

.active {
    background-color: red;
}

.panel {
    font-weight: 400;
    color: hsl(292, 16%, 49%);
    display: none;  
    overflow: hidden;
    margin-bottom: 20px;
    text-align: left;
} 

JavaScript

const acc = document.getElementsByClassName("accordion_btn");
var i;

for (let i = 0; i < acc.length; i++) {
    acc[i].addEventListener("click", (event) => {
        this.classList.toggle("active");
        this.classList.toggle("accordion_btn:hover");

    const panel = this.nextElementSibling;
    if (panel.style.display === "block") {
        panel.style.display = "none";
    } else {
        panel.style.display = "block";
    } 
 });
}

我尝试用

var
const
更改我的变量声明,但这可能与它无关?我还尝试在原始 HTML 文件中添加 defer 到我的脚本标记。

javascript toggle accordion
1个回答
0
投票

因为

this
指向对象窗口 所以你只需要将每个
this
更改为
acc[i]

这是工作代码

const acc = document.getElementsByClassName("accordion_btn");
var i;

for (let i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", (event) => {
    acc[i].classList.toggle("active");
    acc[i].classList.toggle("accordion_btn:hover");

    const panel = acc[i].nextElementSibling;
    if (panel.style.display === "block") {
      panel.style.display = "none";
    } else {
      panel.style.display = "block";
    }
  });
}
.accordion_btn {
    width: 100%;
    background-color: hsl(0, 0%, 100%);
    text-align: left; 
    border: none;
    outline: none;
    margin: 20px 0;
    transition: 0.4s; 
}

.accordion_btn:hover {
    background-color: hsl(276, 51%, 90%);
}

.active {
    background-color: red;
}

.panel {
    font-weight: 400;
    color: hsl(292, 16%, 49%);
    display: none;  
    overflow: hidden;
    margin-bottom: 20px;
    text-align: left;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
    <div class="accordion">
      <button class="accordion_btn">
        What is Frontend Mentor, and how will it help me?
      </button>
      <div class="panel">
        <p>Frontend Mentor offers...</p>
      </div>
    </div>

    <div class="accordion">
      <button class="accordion_btn">Is Frontend Mentor free?</button>
      <div class="panel">
        <p>Yes, Frontend Mentor...</p>
      </div>
    </div>

    <div class="accordion">
      <button class="accordion_btn">
        Can I use Frontend Mentor projects in my portfolio?
      </button>
      <div class="panel">
        <p>Yes...</p>
      </div>
    </div>

    <div class="accordion">
      <button class="accordion_btn">
        How can I get help if I'm stuck on a Frontend Mentor challenge?
      </button>
      <div class="panel">
        <p>The best place to...</p>
      </div>
    </div>
    <script src="js/main.js"></script>
  </body>
</html>

© www.soinside.com 2019 - 2024. All rights reserved.