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

JS倒计时功能启动延迟3秒问题求助(附代码)

倒计时启动存在3秒延迟问题

我用JavaScript实现了倒计时功能,倒计时运行正常,但启动阶段会有3秒延迟。项目中负责启动倒计时的是startCount()函数,我尝试重构代码减少回调函数数量来解决延迟问题,但至今没有效果。

核心问题函数 startCount() 代码

function startCount(duration) {

    countDown = setTimeout( () => {
        const minutes = Math.floor(duration / 60);
        const seconds = Math.floor(duration % 60);
        
        secondsDisplay.textContent = seconds < 10 ? '0' + seconds : seconds;
        minutesDisplay.textContent = minutes < 10 ? '0' + minutes : minutes;
        
        duration--;
        
        if(duration >= 0 ) {
            startCount(duration)
        }
        else {
            resetDisplay()
            toggleButtons()
        }
        console.log(duration)

    }, 1000)
}

完整项目代码

const startButton = document.querySelector('#startButton')
const stopButton = document.querySelector('#stopButton')
const pomodoroButton = document.querySelector('#pomodoroButton')
const breakButton = document.querySelector('#breakButton')
const longBreakButton = document.querySelector('#longBreakButton')
const soundOnButton = document.querySelector('#soundOnButton')
const soundOffButton = document.querySelector('#soundOffButton')
const addTimeButton = document.querySelector('#addTimeButton')
const removeTimeButton = document.querySelector('#removeTimeButton')

const oneNightInTokyo = new Audio('src/music/ONE NIGHT IN TOKYO (320 kbps).mp3')

const secondsDisplay = document.querySelector('#seconds')
const minutesDisplay = document.querySelector('#minutes')

const seconds = parseInt(secondsDisplay.textContent)
const minutes = parseInt(minutesDisplay.textContent)

let countDown;
let duration;

startButton.addEventListener('click', () => {
    const seconds = parseInt(secondsDisplay.textContent)
    const minutes = parseInt(minutesDisplay.textContent)
    let duration = (minutes * 60) + seconds;

    startCount(duration)
    toggleButtons()
})
stopButton.addEventListener('click', stopCount)
pomodoroButton.addEventListener('click', () => {
    minutesDisplay.textContent = 25;
    secondsDisplay.textContent = '00';

    clearTimeout(countDown)
    startButton.classList.remove('hide')
    stopButton.classList.add('hide')
})
breakButton.addEventListener('click', () => {
    minutesDisplay.textContent = '05';
    secondsDisplay.textContent = '00';
    
    clearTimeout(countDown)
    startButton.classList.remove('hide')
    stopButton.classList.add('hide')
})
longBreakButton.addEventListener('click', () => {
    minutesDisplay.textContent = 15;
    secondsDisplay.textContent = '00';

    clearTimeout(countDown)
    startButton.classList.remove('hide')
    stopButton.classList.add('hide')
})
soundOnButton.addEventListener('click', () => {
    oneNightInTokyo.play()
    oneNightInTokyo.volume = 0.2;
    toggleSoundButtons()
})
soundOffButton.addEventListener('click', () => {
    oneNightInTokyo.pause()
    toggleSoundButtons()
})
addTimeButton.addEventListener('click',() => {
    const minutes = parseInt(minutesDisplay.textContent);
    const seconds = parseInt(secondsDisplay.textContent);
    minutesDisplay.textContent = minutes + 1;
    duration = (minutes + 1) * 60 + seconds;
    clearTimeout(countDown)
    startButton.classList.remove('hide')
    stopButton.classList.add('hide')
})
removeTimeButton.addEventListener('click', () => {
    const minutes = parseInt(minutesDisplay.textContent);
    const seconds = parseInt(secondsDisplay.textContent);
    if (minutes > 1) {
        minutesDisplay.textContent = minutes - 1;
        duration = (minutes - 1) * 60 + seconds;
    } 
    clearTimeout(countDown)
    startButton.classList.remove('hide')
    stopButton.classList.add('hide')

})



function resetDisplay() {
    minutesDisplay.textContent = minutes < 10 ? '0' + minutes : minutes;
    secondsDisplay.textContent = seconds < 10 ? '0' + seconds : seconds;
}

function stopCount() {
    clearTimeout(countDown)
    toggleButtons()
}

function startCount(duration) {

    countDown = setTimeout( () => {
        const minutes = Math.floor(duration / 60);
        const seconds = Math.floor(duration % 60);
        
        secondsDisplay.textContent = seconds < 10 ? '0' + seconds : seconds;
        minutesDisplay.textContent = minutes < 10 ? '0' + minutes : minutes;
        
        duration--;
        
        if(duration >= 0 ) {
            startCount(duration)
        }
        else {
            resetDisplay()
            toggleButtons()
        }
        console.log(duration)

    }, 1000)
}

function toggleButtons(){
    startButton.classList.toggle('hide')
    stopButton.classList.toggle('hide')
}
function toggleSoundButtons() {
    soundOnButton.classList.toggle('hide')
    soundOffButton.classList.toggle('hide')
}

内容的提问来源于stack exchange,提问作者Pedro Henrique

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 06:45:07