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

Accordion复制文本触发关闭及点击外部自动关闭问题求解

Accordion组件问题解决方案

问题1:复制文本时触发Accordion关闭

解决思路

原代码将点击事件绑定在整个.content-container上,导致用户复制文本时的鼠标操作会误触折叠逻辑。我们可以将点击事件仅绑定到.question元素,只有点击问题标题才切换面板状态,避免内容区域的操作触发折叠。

修改后的核心JS逻辑

const accordionPanels = document.querySelectorAll(".content-container");
const questions = document.querySelectorAll(".question");

questions.forEach(question => {
  question.addEventListener("click", function() {
    const panel = this.parentElement;
    const isActive = panel.classList.contains("active");
    
    // 先关闭所有面板
    accordionPanels.forEach(p => p.classList.remove("active"));
    
    // 当前面板未激活则打开它
    if (!isActive) {
      panel.classList.add("active");
    }
  });
});

问题2:点击外部区域自动关闭Accordion

解决思路

给window添加点击事件监听,通过Element.contains()方法判断点击目标是否在Accordion内部。如果点击的是外部区域,则移除所有面板的active类,实现自动关闭。

补充代码(添加到JS末尾)

window.addEventListener("click", function(e) {
  const accordion = document.querySelector(".accordion");
  // 判断点击目标是否不属于Accordion内部元素
  if (!accordion.contains(e.target)) {
    accordionPanels.forEach(panel => panel.classList.remove("active"));
  }
});

完整修改后的JS代码

const accordionPanels = document.querySelectorAll(".content-container");
const questions = document.querySelectorAll(".question");

// 绑定问题标题的点击切换逻辑
questions.forEach(question => {
  question.addEventListener("click", function() {
    const panel = this.parentElement;
    const isActive = panel.classList.contains("active");
    
    accordionPanels.forEach(p => p.classList.remove("active"));
    
    if (!isActive) {
      panel.classList.add("active");
    }
  });
});

// 点击外部区域关闭所有面板
window.addEventListener("click", function(e) {
  const accordion = document.querySelector(".accordion");
  if (!accordion.contains(e.target)) {
    accordionPanels.forEach(panel => panel.classList.remove("active"));
  }
});

原HTML与SCSS代码(无需修改)

HTML

<div class="accordion">
  <h2 class="accordion-title">Frequently asked questions</h2>
  <div class="content-container active">
    <div class="question">What is the return Policy</div>
    <div class="answer">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Incidunt dolores non eaque beatae dolor veniam amet, molestiae neque quibusdam ipsa!</div>
  </div>
  <div class="content-container">
    <div class="question">Where can you find us</div>
    <div class="answer">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Incidunt dolores non eaque beatae dolor veniam amet, molestiae neque quibusdam ipsa!</div>
  </div>
  <div class="content-container">
    <div class="question">Some other text</div>
    <div class="answer">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Incidunt dolores non eaque beatae dolor veniam amet, molestiae neque quibusdam ipsa!</div>
  </div>
</div>

SCSS

.accordion{
    margin: 0 auto;
    width: 60%;
    border-color: #fff;
    padding: 2rem;
    border-radius: 30px;
    &-title{
        margin-bottom: 2rem;
        text-align: center;
    }
    .content-container
        .question{
            padding: 1rem 0;
            font-size: 22px;
        cursor: pointer;
        border-bottom: 1px solid #000;
        position: relative;
        &::after{
            content: "+";
            position: absolute;
            right: -5px;

        }
        }
        .answer{
           padding-top: 1rem;
           font-size: 22px;
           line-height: 1.5;
           width: 100%; 
           height: 0px;
           overflow: hidden;
           transition: all .5s;
        }
}

// js styling link

.accordion .content-container.active{
    .question{

        &::after{
            content: "-";
            font-size: 2rem;
            transition: .5s;
        }
    }
    .answer{
        height: 150px;
    }
}

内容的提问来源于stack exchange,提问作者Filip Drábek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 02:50:21