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

如何避免JavaScript keydown事件在动画未完成时重复触发?

解决键盘快速连续触发导致动画异常的问题

你遇到的是典型的重复触发异步操作导致的动画堆积问题,核心思路是给上下滑动的操作分别加「执行锁」,在当前动画未完成前,拒绝同方向的下一次触发。具体实现步骤如下:

实现方案

  1. 定义两个状态变量作为执行锁,分别控制上下滑动的触发权限
  2. 在slideDown()和slideUp()内部先检查锁状态:如果当前正在执行对应动画,直接返回;否则锁定并执行动画,动画结束后解锁
  3. 事件监听逻辑保持原有判断,但依赖加锁后的滑动函数

修改后的完整代码

// 初始化执行锁,默认未锁定
let isSlidingDown = false;
let isSlidingUp = false;

function slideDown() {
    // 如果正在执行下滑动画,直接返回
    if (isSlidingDown) return;
    
    // 锁定下滑操作
    isSlidingDown = true;
    
    // 这里是你的下滑动画逻辑,比如DOM操作、CSS过渡等
    // 示例:假设动画时长为300ms,动画结束后解锁
    // 如果是用CSS transition/animation,建议监听transitionend/animationend事件来解锁
    setTimeout(() => {
        // 动画完成后解锁
        isSlidingDown = false;
    }, 300);
}

function slideUp() {
    // 如果正在执行上滑动画,直接返回
    if (isSlidingUp) return;
    
    // 锁定上滑操作
    isSlidingUp = true;
    
    // 你的上滑动画逻辑
    setTimeout(() => {
        // 动画完成后解锁
        isSlidingUp = false;
    }, 300);
}

window.addEventListener("keydown", (e) => {
    if (e.key === "ArrowDown") slideDown();
    if (e.key === "ArrowUp") slideUp();
    myName.style.color = counter === 3 ? "white" : "black";
})

关键细节说明

  • 如果你用的是CSS过渡/动画,不要用setTimeout来解锁,应该监听元素的transitionend或animationend事件,确保动画真正结束后才解锁,比如:
    function slideDown() {
        if (isSlidingDown) return;
        isSlidingDown = true;
        
        // 执行动画操作,比如添加类名
        targetElement.classList.add("slide-down");
        
        // 监听动画结束事件({ once: true }确保事件只触发一次)
        targetElement.addEventListener("transitionend", function unlock() {
            isSlidingDown = false;
            targetElement.classList.remove("slide-down");
            targetElement.removeEventListener("transitionend", unlock);
        }, { once: true });
    }
    
  • 锁变量分开控制上下方向,不会影响相反方向的操作;如果需要完全禁止所有操作,可以合并成一个全局锁变量

内容的提问来源于stack exchange,提问作者Abdel Rahman Yosry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 23:41:11