You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Accordion菜单JavaScript报错排查与功能修复求助

解决Accordion菜单的TypeError: Cannot read properties of undefined (reading 'toggle')问题

问题根源

  1. 箭头函数的this绑定错误:你用箭头函数作为点击事件处理函数,箭头函数不会创建独立的this上下文,会继承外层作用域的this。这里外层是全局作用域,this指向undefined(严格模式下),调用this.classList.toggle自然会抛出TypeError。
  2. 错误操作CSS伪类:this.classList.toggle("accordion_btn:hover")完全无效,:hover是CSS伪类,不属于元素的类名集合,无法通过classList来切换。

修复方案

1. 替换箭头函数为普通函数

普通函数作为事件处理函数时,this会自动绑定到触发事件的DOM元素(即点击的按钮)。

2. 移除伪类切换逻辑,用CSS规则实现状态变化

通过CSS优先级,让.active类的样式覆盖默认或hover状态的样式,或者单独定义.accordion_btn.active:hover的样式。

3. 用CSS类控制面板显示(更易维护)

替代直接修改style.display,通过切换类来控制面板的显示/隐藏,符合样式与逻辑分离的原则。

修复后的完整代码

JavaScript

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

for (let i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    // 切换按钮的active类
    this.classList.toggle("active");
    // 获取对应面板并切换显示类
    const panel = this.nextElementSibling;
    panel.classList.toggle("show");
  });
}

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状态样式,覆盖默认样式 */
.accordion_btn.active {
  background-color: red;
}

/* active状态下的hover样式(可选) */
.accordion_btn.active:hover {
  background-color: darkred;
}

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

/* 用类控制面板显示 */
.panel.show {
  display: block;
}

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>

额外说明

如果坚持要用箭头函数,可以通过event.currentTarget获取触发事件的按钮元素替代this:

acc[i].addEventListener("click", (event) => {
  const btn = event.currentTarget;
  btn.classList.toggle("active");
  const panel = btn.nextElementSibling;
  panel.classList.toggle("show");
});

内容的提问来源于stack exchange,提问作者Adritriz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 20:35:18