Следующий код jquery запускает таймер для всех совпадающих элементов

$.each($('.product, #auction-div'), function () {
    var deadline = new Date(0);
    deadline.setUTCMilliseconds($(this).find('input[name=startDate]').val());
    initializeClock($(this).find('.clockdiv'), deadline);
});

Позже моя страница получает обновление, и обновление содержит обновленное оставшееся время обратного отсчета. Мне нужно вызвать функцию initializeClock, оставив текущее время обратного отсчета, как в следующем коде.

        success: function (data) {
            comet = subscribe();
            var auction = data.auction;
            if (auction) {
                var productBox = $('#' + data.auction.uid);
                productBox.find('.timer').html('09');
                productBox.find('.auction-price, #auction-price').html('KSh.' + data.auction.auctionValue);
                audio.play();
                var deadline = new Date(0);
                deadline.setUTCMilliseconds(data.countdown);
                initializeClock(productBox.find('.clockdiv'), deadline);
            }
        },

Это код для initializeClock и других соответствующих функций

//    code for countdown timer
    function getTimeRemaining(endtime) {
        var t = Date.parse(endtime) - Date.parse(new Date());
        var seconds = Math.floor((t / 1000) % 60);
        var minutes = Math.floor((t / 1000 / 60) % 60);
        var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
        var days = Math.floor(t / (1000 * 60 * 60 * 24));
        if (t < 0) {
            days = hours = minutes = seconds = 0;
        }
        return {
            'total': t,
            'days': days,
            'hours': hours,
            'minutes': minutes,
            'seconds': seconds
        };
    }
    function initializeClock(clock, endtime) {
        var daysSpan = clock.find('.days');
        var hoursSpan = clock.find('.hours');
        var minutesSpan = clock.find('.minutes');
        var secondsSpan = clock.find('.seconds');
        function updateClock() {
            var t = getTimeRemaining(endtime);
            daysSpan.html(t.days);
            hoursSpan.html(('0' + t.hours).slice(-2));
            minutesSpan.html(('0' + t.minutes).slice(-2));
            secondsSpan.html(('0' + t.seconds).slice(-2));
            if (t.total <= 0) {
                clearInterval(timeinterval);
            }
        }
        updateClock();
        var timeinterval = setInterval(updateClock, 1000);
    }

К сожалению, это приводит к тому, что на clockDiv инициализируются несколько часов, а обратный отсчет становится все более хаотичным.

Я пробовал следующие методы, прежде чем впоследствии инициализировать часы

  1. .clearQueue()
  2. И вызывая .stop(), хотя мне пришлось попробовать его для анимации`
  3. Затем я не хочу пытаться удалить родительский элемент, содержащий div часов, и снова заменить его, чтобы увидеть, не отвяжет ли это связанные события.

Тем временем я надеюсь, что есть однострочное элегантное решение.

PS У меня нет ссылки на какую-либо переменную, которую я мог бы вызвать clearInterval(timeinterval);, поэтому давайте не будем на этом останавливаться.

0
qualebs 1 Янв 2018 в 15:34

2 ответа

Лучший ответ

Вам необходимо установить свойство timer для самого элемента , чтобы вы могли использовать его в следующий раз.

function initializeClock(clock, endtime) {
    var timeinterval = clock.prop( "clockTimer" );
    if ( timeinterval )
    {
        return; //timer already started on this, so no need to create a new one
    }
    //rest of the code

    timeinterval = setInterval(updateClock, 1000);
    clock.prop( "clockTimer", timerInterval );
}

Как остановить функции таймера на элементе

Вы можете реализовать функцию stop

function stopTimer( clock )
{
        var timeinterval = clock.prop( "clockTimer" );
        if ( timeinterval )
        {
            clearInterval( timeInterval );
        }
}
1
gurvinder372 1 Янв 2018 в 12:48

К сожалению, initializeClock не возвращает дескриптор таймера и не хранит его в любом месте, где вы можете получить к нему доступ. Итак, у вас есть два варианта:

  1. Если у вас есть доступ к initializeClock (или вы можете сообщить кому-то, у кого есть доступ к нему, изменить его), измените его так, чтобы он сохранял дескриптор таймера для рассматриваемого элемента (возможно, используя jQuery data метод). Затем вы можете получить его и очистить предыдущий интервальный таймер перед запуском следующего.

  2. Если у вас нет доступа к нему, гораздо хуже , чем вариант №1, - удалить элемент и заменить его клоном (возможно, через jQuery clone и replaceWith методы). Таким образом, хотя старый интервальный таймер все еще работает (у нас нет возможности его остановить), элемент, который он обновляет, больше не находится в DOM и больше не отображается на странице.

№2 - это скорее обходной путь, а не решение, потому что со временем вы будете создавать интервальные таймеры, которые работают без уважительной причины.

0
T.J. Crowder 1 Янв 2018 в 12:45