如何为同一类或ID批量使用classList.toggle以避免代码重复?
优化重复代码并解决仅第一个元素生效的问题
问题分析
你当前代码存在两个核心问题:
- 重复编写相同的点击逻辑,每个项目单独实现一遍,维护成本高
- 箭头动画仅第一个生效,是因为你固定选中了第一个
.arrow-down元素,所有点击操作都指向它,而非当前点击项目的箭头
优化方案
通过DOM父子关系定位元素,复用同一套逻辑处理所有项目,无需依赖id区分元素:
优化后的HTML
给内容区块添加统一类名.projet-content,移除不必要的id(保留id也不影响,但类名更适合批量操作):
<body> <section> <div class="projet-contain"> <div class="preview"> <a>Projet Convertigo</a> <svg class="arrow-down" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-down" viewBox="0 0 16 16"> <path d="M3.204 5h9.592L8 10.481 3.204 5zm-.753.659 4.796 5.48a1 1 0 0 0 1.506 0l4.796-5.48c.566-.647.106-1.659-.753-1.659H3.204a1 1 0 0 0-.753 1.659z"/> </svg> <img src="images/Convertigo.png" class="convertigo" alt=""> </div> <div class="projet-content"> <a>c'est la div 1</a> </div> </div> <div class="projet-contain"> <div class="preview"> <a>Projet Convertigo</a> <svg class="arrow-down" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-down" viewBox="0 0 16 16"> <path d="M3.204 5h9.592L8 10.481 3.204 5zm-.753.659 4.796 5.48a1 1 0 0 0 1.506 0l4.796-5.48c.566-.647.106-1.659-.753-1.659H3.204a1 1 0 0 0-.753 1.659z"/> </svg> <img src="images/Convertigo.png" class="convertigo" alt=""> </div> <div class="projet-content"> <a>c'est la div 2</a> </div> </div> <div class="projet-contain"> <div class="preview"> <a>Projet Convertigo</a> <svg class="arrow-down" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-down" viewBox="0 0 16 16"> <path d="M3.204 5h9.592L8 10.481 3.204 5zm-.753.659 4.796 5.48a1 1 0 0 0 1.506 0l4.796-5.48c.566-.647.106-1.659-.753-1.659H3.204a1 1 0 0 0-.753 1.659z"/> </svg> <img src="images/Convertigo.png" class="convertigo" alt=""> </div> <div class="projet-content"> <a>c'est la div 3</a> </div> </div> </section> </body>
优化后的CSS
直接用CSS默认隐藏内容区块,比JS设置更高效:
.projet-contain{ display: flex; flex-direction: column; margin-bottom: 50px; width: auto; height: auto; background: radial-gradient(circle, rgba(238,174,202,0.200) 0%, rgba(148, 188, 233, 0.200) 100%); border-radius: 10px 10px 10px 10px; padding: 10px; user-select: none; } .preview{ display: flex; justify-content: space-between; align-items: center; } section >div>div >a { text-decoration: none; color: white; } .convertigo{ width: 10vw; } .arrow-down { transition: transform 0.5s; width: 1.5vw; -webkit-filter: invert(100%); /* safari 6.0 - 9.0 */ filter: invert(100%); } .rotate-arrow { transform: rotate(180deg); } /* 默认隐藏内容区块 */ .projet-content { display: none; } body{ background:purple; }
优化后的JavaScript
通过循环给所有项目绑定点击事件,利用this获取当前点击的容器,再找到对应的箭头和内容:
// 获取所有项目容器 const projetContainers = document.querySelectorAll('.projet-contain'); // 给每个容器绑定点击事件 projetContainers.forEach(container => { container.onclick = function() { // 找到当前容器内的内容区块和箭头 const content = this.querySelector('.projet-content'); const arrow = this.querySelector('.arrow-down'); // 切换内容显示状态 content.style.display = content.style.display !== 'flex' ? 'flex' : 'none'; // 切换箭头旋转状态 arrow.classList.toggle('rotate-arrow'); } });
优化点说明
- 不再依赖id,新增/删除项目时无需修改JS代码
- 逻辑复用,仅写一次点击处理函数
- 每个点击操作只影响当前项目的箭头和内容,解决了箭头动画仅第一个生效的问题
- 用CSS默认隐藏内容,减少JS初始化逻辑
内容的提问来源于stack exchange,提问作者Ravnow
相关产品推荐
相关产品推荐

