Как приостановить и возобновить таймер JavaScript

У меня есть этот таймер, который работает нормально, но мне нужно иметь возможность приостановить и возобновить его после этого. Я был бы признателен, если бы кто-нибудь мог мне помочь.

<html>
<head>
<script>
function startTimer(m,s)
    {
        document.getElementById('timer').innerHTML= m+":"+s;
        if (s==0)
            {
               if (m == 0)
                {
                    return;
                }
                else if (m != 0)
                {
                    m = m-1;
                    s = 60;
                }
        }
    s = s-1;
    t=setTimeout(function(){startTimer(m,s)},1000);
}


</script>
</head>

<body>
<button onClick = "startTimer(5,0)">Start</button>

<p id = "timer">00:00</p>
</body>
</html>

person user2303981    schedule 21.04.2013    source источник
comment
Если вы не работаете с объектами Date, вам нужно, чтобы ваш таймер работал намного быстрее, сохраняя переменную счетчика в актуальном состоянии, чтобы при вызове clearTimeout у вас было более точное отражение того, где вы были, когда вы возобновите. Если вы работаете с объектами даты, запишите время паузы и время возобновления, и вы сможете рассчитать разницу и учесть ее.   -  person Paul S.    schedule 21.04.2013


Ответы (2)


Я просто не могу видеть setTimeout(...,1000) и ожидать, что это ровно 1000 миллисекунд. Новость: это не так. На самом деле, в зависимости от вашей системы, это может быть где-то между 992 и 1008, и эта разница будет суммироваться.

Я собираюсь показать вам таймер с паузой и дельта-таймингом для обеспечения точности. Единственный способ, чтобы это не было точным, - это изменить часы вашего компьютера в середине этого.

function startTimer(seconds, container, oncomplete) {
    var startTime, timer, obj, ms = seconds*1000,
        display = document.getElementById(container);
    obj = {};
    obj.resume = function() {
        startTime = new Date().getTime();
        timer = setInterval(obj.step,250); // adjust this number to affect granularity
                            // lower numbers are more accurate, but more CPU-expensive
    };
    obj.pause = function() {
        ms = obj.step();
        clearInterval(timer);
    };
    obj.step = function() {
        var now = Math.max(0,ms-(new Date().getTime()-startTime)),
            m = Math.floor(now/60000), s = Math.floor(now/1000)%60;
        s = (s < 10 ? "0" : "")+s;
        display.innerHTML = m+":"+s;
        if( now == 0) {
            clearInterval(timer);
            obj.resume = function() {};
            if( oncomplete) oncomplete();
        }
        return now;
    };
    obj.resume();
    return obj;
}

И используйте это для запуска/паузы/возобновления:

// start:
var timer = startTimer(5*60, "timer", function() {alert("Done!");});
// pause:
timer.pause();
// resume:
timer.resume();
person Niet the Dark Absol    schedule 21.04.2013
comment
как я могу добавить функцию сброса, этот сброс запускает таймер заново? - person Lukas Baliūnas; 08.09.2016
comment
@LukasBaliūnas Переменная ms отслеживает оставшиеся миллисекунды. Вы можете добавить obj.reset = function() {ms = seconds*1000;} в функцию startTimer и вызвать timer.reset() для осуществления сброса. Однако обратите внимание, что если таймер уже завершился, то .resume() ничего не сделает - вам может потребоваться удалить строку obj.resume = function() {}, чтобы позволить ему запуститься во второй раз после сброса. - person Niet the Dark Absol; 08.09.2016
comment
еще один, как бы я добавил функцию, чтобы добавить секунду или уменьшить секунду на таймере? будет выполняться либо во время работы таймера, либо во время паузы. Благодарность - person Lukas Baliūnas; 12.09.2016
comment
obj.modify = function(diff) {ms += diff*1000;} - введите timer.modify(+1), чтобы добавить одну секунду, modifiy(-2), чтобы вычесть две... - person Niet the Dark Absol; 12.09.2016

<p id="timer">00:00</p>
<button id="start">Start</button>
<button id="pause">Pause</button>
<button id="resume">Resume</button>

var timer = document.getElementById("timer");
var start = document.getElementById("start");
var pause = document.getElementById("pause");
var resume = document.getElementById("resume");
var id;
var value = "00:00";

function startTimer(m, s) {
    timer.textContent = m + ":" + s;
    if (s == 0) {
        if (m == 0) {
            return;
        } else if (m != 0) {
            m = m - 1;
            s = 60;
        }
    }

    s = s - 1;
    id = setTimeout(function () {
        startTimer(m, s)
    }, 1000);
}

function pauseTimer() {
    value = timer.textContent;
    clearTimeout(id);
}

function resumeTimer() {
    var t = value.split(":");

    startTimer(parseInt(t[0], 10), parseInt(t[1], 10));
}

start.addEventListener("click", function () {
    startTimer(5, 0);
}, false);

pause.addEventListener("click", pauseTimer, false);

resume.addEventListener("click", resumeTimer, false);

на jsfiddle

Можно внести множество улучшений, но я придерживаюсь кода, опубликованного ОП для понимания ОП.

Вот расширенная версия, чтобы дать вам дополнительные идеи о jsfiddle.

person Xotic750    schedule 21.04.2013