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

如何用JavaScript高效管理嵌套details标签的闪烁动画?

高效实现嵌套details标签的summary闪烁动画控制

需求说明

  • 为嵌套结构的<details>标签内的<summary>添加闪烁动画
  • 打开<details>时停止闪烁(移除blink类),关闭时恢复闪烁(添加blink类)
  • 后续会新增更多<details>标签,当前为每个标签单独编写脚本,希望找到批量管理的高效方案

现有代码

HTML

<body>
<details id="details_id_1">
<summary id="s_id1" class="blink">summary1</summary>
    <span>contents1</span>    
        <details id="details_id_2">
            <summary id="s_id2" class="blink">summary2</summary>
            <span>contents2</span>    
                <details id="details_id_3">
                    <summary id="s_id3" class="blink">summary3</summary>
                    <span>contents3</span>
                </details>
        </details>
</details>
</body>

JavaScript

<script>
    const details_1 = document.querySelector("#details_id_1");
    const summary = document.querySelector("#s_id1");   
    
    summary.addEventListener("click", (event) => {
        
        if(details_1.open){
            summary.classList.add("blink");
        }else{
            summary.classList.remove("blink");
        }
    });
</script>

<script>
    const details_2 = document.querySelector("#details_id_2");
    const summary_2 = document.querySelector("#s_id2"); 
    
    summary_2.addEventListener("click", (event) => {
        
        if(details_2.open){
            summary_2.classList.add("blink");
        }else{
            summary_2.classList.remove("blink");
        }
    });
</script>

<script>
    const details_3 = document.querySelector("#details_id_3");
    const summary_3 = document.querySelector("#s_id3"); 
    
    summary_3.addEventListener("click", (event) => {
        
        if(details_3.open){
            summary_3.classList.add("blink");
        }else{
            summary_3.classList.remove("blink");
        }
    });
</script>

解决方案

1. 补充闪烁动画的CSS

先定义blink类的动画效果(如果还未添加):

.blink {
  animation: blink 1s infinite;
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

2. 事件委托实现批量控制

不需要给每个details和summary加ID,直接通过事件委托监听所有details的toggle事件,新增的标签会自动生效:

document.addEventListener('toggle', function(event) {
  const details = event.target;
  // 确保触发事件的是details元素
  if (details.tagName === 'DETAILS') {
    const summary = details.querySelector('summary');
    if (summary) {
      // 展开时移除blink类,收起时添加
      summary.classList.toggle('blink', !details.open);
    }
  }
}, true);

代码说明

  • 用toggle事件代替click,能覆盖所有触发展开/收起的操作(比如键盘回车),兼容性更好
  • 事件委托绑定在document上,后续新增的details标签无需额外写绑定代码
  • classList.toggle的第二个参数是条件判断,简化了手动添加/移除类的逻辑

优化后的完整代码

<!DOCTYPE html>
<html>
<head>
  <style>
    .blink {
      animation: blink 1s infinite;
    }

    @keyframes blink {
      0%, 100% { opacity: 1; }
      50% { opacity: 0; }
    }
  </style>
</head>
<body>
<details>
  <summary class="blink">summary1</summary>
  <span>contents1</span>    
  <details>
    <summary class="blink">summary2</summary>
    <span>contents2</span>    
    <details>
      <summary class="blink">summary3</summary>
      <span>contents3</span>
    </details>
  </details>
</details>

<script>
document.addEventListener('toggle', function(event) {
  const details = event.target;
  if (details.tagName === 'DETAILS') {
    const summary = details.querySelector('summary');
    if (summary) {
      summary.classList.toggle('blink', !details.open);
    }
  }
}, true);
</script>
</body>
</html>

内容的提问来源于stack exchange,提问作者Son-Bin-O

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 10:45:33