首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JS 導航欄滑塊跟隨鼠標移動的定時器衝突 Bug 修復

     編輯:程式設計綜合問答

Bug 現象

鼠標快速在導航項之間來回移動,滑塊會卡在某位置停止響應。

根本原因

move() 中每次調用 setInterval 前**未清除上一個定時器**,導致多個定時器並行修改同一元素 style.left,互相覆蓋、邏輯混亂。

修復核心:先清後開

var timer = null; // 模塊級變量持有定時器 ID

function move(a) {
    clearInterval(timer); // 關鍵:清除舊定時器
    var target = a * 130;
    var current = parseInt(tt.style.left) || 0;
    
    if (current > target) {
        timer = setInterval(() => moveLeft(target), 30);
    } else if (current < target) {
        timer = setInterval(() => moveRight(target), 30);
    }
}

進階優化:requestAnimationFrame

定時器 30ms 間隔在高刷屏上不夠平滑,建議用 requestAnimationFrame 實現緩動動畫:

function animateTo(target) {
    var start = parseInt(tt.style.left) || 0;
    var duration = 300; // ms
    var startTime = performance.now();
    
    function step(now) {
        var elapsed = now - startTime;
        var progress = Math.min(elapsed / duration, 1);
        // ease-out
        var eased = 1 - Math.pow(1 - progress, 3);
        tt.style.left = (start + (target - start) * eased) + 'px';
        if (progress < 1) requestAnimationFrame(step);
    }
    requestAnimationFrame(step);
}

完整修正版關鍵點

  1. 全局 timer 變量,每次 move 先 clearInterval。
  2. 目標位置計算用 a * 130,避免重複解析。
  3. 邊界檢查:Math.min/max 確保不超出範圍。
  4. 可選:添加 transition: left 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94) 純 CSS 動畫,完全避免 JS 定時器。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved