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

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>

问题原因
  1. 动态元素集合导致的查询异常:使用document.getElementsByClassName获取的是动态HTMLCollection,每次调用Array.from(achievements)都会重新查询DOM。当给.achievement元素添加transform后,元素布局位置改变,后续查询会出现异常,甚至丢失事件绑定。
  2. 按钮被滚动元素覆盖:箭头按钮是position: absolute但未设置z-index,当.achievement元素通过translateY移动后,会覆盖在按钮上方,导致鼠标实际触发的是成就元素而非按钮,:hover和点击事件全部失效。
  3. 重复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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 21:15:39