HTML箭头按钮点击一次后功能完全失效的问题及解决方法
问题描述
我编写了一段实现成就列表上下滚动交互的代码,点击上下箭头按钮时,按钮仅能正常工作一次,之后不仅scrollAcievements函数不再执行,就连CSS的:hover颜色变化效果也完全消失。代码片段如下:
JavaScript 代码
let achievements = document.getElementsByClassName('achievement'); let viewEl = 1; let posY = 0; function scrollAcievements(direction){ console.log('ENT'); if (direction == 'U') { viewEl++; posY -= 300; } else if (direction == 'D') { viewEl--; posY += 300; } if (viewEl < 1) { viewEl = 1; posY = 0; return null; } else if (viewEl > Array.from(achievements).length) { viewEl = Array.from(achievements).length; posY = Array.from(achievements).length*300 - 300; return null; } console.log(viewEl); console.log(posY); (Array.from(achievements)).forEach(element => { element.style.transform = `translateY(${posY}px)`; }); console.log('EX'); }
CSS 代码
.achievement{ height: 400px; transition: 0.2s; } .achievements-holder{ transition: 0.2s; background-color: transparent; position: relative; height: 400px; padding: 50px 10px; margin: 5px; overflow-y: hidden; } .achievements-holder section div{ display: flex; flex-direction: column; flex-grow: 1; } .achievements-holder section{ display: flex; width: 100%; height: 300px; } .achievements-holder .heading{ background-color: transparent; font-size: 2.5rem; flex-grow: 1; } .achievements-holder .data{ background-color: transparent; text-align: right; margin: 5px; } .achievements-arrow{ position: absolute; left: 50%; transform: rotate(-90deg); } .funky-h3:hover{ color: #1adb61; } .funky-h3{ font-size: 1.5rem; font-family: 'Press Start 2P', cursive; margin: 15px 0; color: #17c758; user-select: none; }
HTML 代码
<script src="https://cdn.tailwindcss.com"></script> <div class="container px-5 py-24 mx-auto flex-row"> <h1 class="content-heading" id="aboutme"> achievements( </h1> <div class="flex flex-wrap w-full achievements-holder"> <div class="funky-h3 achievements-arrow" id=" UP" onclick="scrollAcievements('U');">></div> <div class="funky-h3 achievements-arrow" id="DOWN" onclick="scrollAcievements('D');" style="bottom: 0%;"><<</div> <section class="flex-row achievement" id="JEE"> <div> <img src="https://img.collegepravesh.com/2015/09/NTA-Logo.png" style="aspect-ratio: 1; width: 100px;" alt=""> <h1 class="heading"> HEEAD </h1> </div> <h1 class="funky-h3 data"> DATA GAIN </h1> </section> <section class="flex-row achievement" id="WBJEE"> <div> <img src="https://upload.wikimedia.org/wikipedia/en/thumb/4/46/West_Bengal_Joint_Entrance_Examinations_Board_Logo.svg/220px-West_Bengal_Joint_Entrance_Examinations_Board_Logo.svg.png" style="aspect-ratio: 1; width: 100px;" alt=""> <h1 class="heading"> HEAD </h1> </div> <h1 class="funky-h3 data"> STFF </h1> </section> <section class="flex-row achievement" id="WBJEE"> <div> <img src="https://img.collegepravesh.com/2015/09/NTA-Logo.png" style="aspect-ratio: 1; width: 100px;" alt=""> <h1 class="heading"> CUET </h1> </div> <h1 class="funky-h3 data"> centile </h1> </section> </div> <h1 class="content-heading" id="aboutme"> ); </h1> </div>
问题原因
- 动态元素集合导致的查询异常:使用
document.getElementsByClassName获取的是动态HTMLCollection,每次调用Array.from(achievements)都会重新查询DOM。当给.achievement元素添加transform后,元素布局位置改变,后续查询会出现异常,甚至丢失事件绑定。 - 按钮被滚动元素覆盖:箭头按钮是
position: absolute但未设置z-index,当.achievement元素通过translateY移动后,会覆盖在按钮上方,导致鼠标实际触发的是成就元素而非按钮,:hover和点击事件全部失效。 - 重复ID问题:HTML中有两个元素ID为
WBJEE,属于DOM结构错误,会引发潜在的查询异常。
修复方案
1. 静态获取元素集合
将动态的HTMLCollection转为静态数组,避免重复查询DOM:
// 一次性获取并转为静态数组 const achievements = Array.from(document.getElementsByClassName('achievement')); let viewEl = 1; let posY = 0; function scrollAcievements(direction){ console.log('ENT'); const maxEl = achievements.length; if (direction === 'U') { viewEl = Math.min(viewEl + 1, maxEl); } else if (direction === 'D') { viewEl = Math.max(viewEl - 1, 1); } // 直接根据当前显示项计算偏移量,简化边界判断 posY = -(viewEl - 1) * 300; console.log(viewEl); console.log(posY); achievements.forEach(element => { element.style.transform = `translateY(${posY}px)`; }); console.log('EX'); }
2. 提升按钮层级
修改CSS,给箭头按钮添加z-index确保其在成就元素上方:
.achievements-arrow{ position: absolute; left: 50%; transform: rotate(-90deg); z-index: 10; /* 确保按钮在最上层 */ cursor: pointer; /* 可选:添加鼠标指针样式,提升交互感知 */ }
3. 修复重复ID问题
将重复的id="WBJEE"改为唯一值:
<section class="flex-row achievement" id="CUET"> <div> <img src="https://img.collegepravesh.com/2015/09/NTA-Logo.png" style="aspect-ratio: 1; width: 100px;" alt=""> <h1 class="heading"> CUET </h1> </div> <h1 class="funky-h3 data"> centile </h1> </section>
内容的提问来源于stack exchange,提问作者Broteen Das
相关产品推荐
相关产品推荐

