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

JavaScript 定時器衝突解決:變數提升與 clearInterval 最佳實踐

     編輯:程式設計綜合問答

問題:點擊按鈕啟動定時器移動方塊,動畫未完成時再次點擊其他按鈕,舊定時器未清除導致多個定時器並行、方塊亂跳。

錯誤程式碼片段

var timer = null;
function show(jc) {
    if (parseInt(tt) < jc*300) {
        timer = setInterval(() => right(jc), 30); // 覆蓋 timer,舊定時器失去引用無法清除
    } else {
        timer = setInterval(() => left(jc), 30);
    }
}

核心修正:啟動前先清除

function show(jc) {
    clearInterval(timer); // 關鍵:清除舊定時器
    if (parseInt(tt) < jc*300) {
        timer = setInterval(() => right(jc), 30);
    } else {
        timer = setInterval(() => left(jc), 30);
    }
}

進階封裝:動畫類

class Slider {
    constructor(el, step=30, duration=30) {
        this.el = el; this.step = step; this.duration = duration;
        this.timer = null; this.target = 0;
    }
    moveTo(pos) {
        clearInterval(this.timer);
        this.target = pos;
        this.timer = setInterval(() => this.tick(), this.duration);
    }
    tick() {
        const cur = parseInt(this.el.style.left) || 0;
        if (Math.abs(cur - this.target) <= this.step) {
            this.el.style.left = this.target + 'px';
            clearInterval(this.timer);
        } else {
            this.el.style.left = (cur + (this.target > cur ? this.step : -this.step)) + 'px';
        }
    }
}
// 使用
const slider = new Slider(document.getElementById('B'));
document.querySelectorAll('.btn').forEach((btn, i) => {
    btn.onclick = () => slider.moveTo(i * 300);
});

關鍵點總結

  • 全域/成員變數儲存 timer ID。
  • 每次啟動新動畫前 無條件 clearInterval(timer)。
  • 封裝為類別避免全域變數污染,支援多實例。
  • 現代專案可改用 requestAnimationFrame + CSS Transition 更流暢。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved