TatsuSheva Ответов: 2

Как установить обратный отсчет в реальном времени в HTML/javascript


Здравствуйте, я хочу сделать обратный отсчет и разместить его на своем сайте. Я сделал обратный отсчет, но у меня есть проблема, когда я запускаю его, секунды замерзают, они больше не бегут... Так что обратный отсчет больше не идет в реальном времени...
Вот что я сделал:

<span id="dhour"></span> h <span id="dmin"></span> min <span id="dsec"></span> sec
<div id="count2"></div>
<div class="numbers" id="dday" hidden="true"></div>
<script>
    var montharray = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
    var year;
    var month;
    var day;
    var hour = 19;
    var minute = 10;
    var tz = 0;
    var ladate;
    var today;

    function myCallback(json) {

        ladate = new Date(json.dateString);

        year = ladate.getFullYear();
        month = ladate.getMonth() + 1;
        day = ladate.getDate();
        countdown(year, month, day, hour, minute);
    }

    function countdown(yr, m, d, hr, min) {
        theyear = yr;
        themonth = m;
        theday = d;
        thehour = hr;
        theminute = min;
        today = ladate;
        var todayy = today.getYear();
        if (todayy < 1000) {
            todayy += 1900;
        }

        var todaym = today.getMonth();
        var todayd = today.getDate();
        var todayh = today.getHours();
        var todaymin = today.getMinutes();
        var todaysec = today.getSeconds();
        var todaystring1 = montharray[todaym] + " " + todayd + ", " + todayy + " " + todayh + ":" + todaymin + ":" + todaysec;
        var todaystring = Date.parse(todaystring1) + (tz * 1000 * 60 * 60);
        var futurestring1 = (montharray[m - 1] + " " + d + ", " + yr + " " + hr + ":" + min);
        var futurestring = Date.parse(futurestring1) - (today.getTimezoneOffset() * (1000 * 60));
        var dd = futurestring - todaystring;
        var dday = Math.floor(dd / (60 * 60 * 1000 * 24) * 1);
        var dhour = Math.floor((dd % (60 * 60 * 1000 * 24)) / (60 * 60 * 1000) * 1);
        var dmin = Math.floor(((dd % (60 * 60 * 1000 * 24)) % (60 * 60 * 1000)) / (60 * 1000) * 1);
        var dsec = Math.floor((((dd % (60 * 60 * 1000 * 24)) % (60 * 60 * 1000)) % (60 * 1000)) / 1000 * 1);

        if (dday <= 0 && dhour <= 0 && dmin <= 0 && dsec <= 0) {
            document.getElementById('count2').style.display = "inline";
            document.getElementById('after').style.display = "none";

            document.getElementById('dday').style.display = "none";
            document.getElementById('dhour').style.display = "none";
            document.getElementById('dmin').style.display = "none";
            document.getElementById('dsec').style.display = "none";
            document.getElementById('days').style.display = "none";
            document.getElementById('hours').style.display = "none";
            document.getElementById('minutes').style.display = "none";
            document.getElementById('seconds').style.display = "none";
            return;
        } else {
            document.getElementById('count2').style.display = "none";
            document.getElementById('dday').innerHTML = dday;
            document.getElementById('dhour').innerHTML = dhour;
            document.getElementById('dmin').innerHTML = dmin;
            document.getElementById('dsec').innerHTML = dsec;
            setTimeout("countdown(theyear,themonth,theday,thehour,theminute)", 1000);
        }
    }
</script>
<script type="text/javascript" src="http://www.timeapi.org/utc/now.json?callback=myCallback"></script>

Спасибо.

Что я уже пробовал:

Я пытался, но не нашел решения...

ZurdoDev

Отладьте его. Выясните, что происходит.

2 Ответов

Рейтинг:
2

Bob@work

Я не уверен, что timeapi.org это делается, но обратный отсчет, по-видимому, основан на двух заявлениях одного и того же времени:

ladate = new Date(json.dateString);
и
today = ladate;

Кроме того, будущая дата вычитает единицу из следующего месяца, установив ее на текущий месяц, в результате чего код никогда не достигнет тайм-аута вызова
var futurestring1 = (montharray[m - 1] + " " + d + ", " + yr + " " + hr + ":" + min);

Изменив вторую переменную времени на текущее время и не вычитая 1 из будущей даты,
today = new Date();
var futurestring1 = (montharray[m - 0] + " " + d + ", " + yr + " " + hr + ":" + min);

Обратный отсчет начинается с вычисления разницы между будущим временем (latime) и текущим временем (today).

-----------

Кроме того, в предоставленном html-коде отсутствуют объекты с идентификатором objectid [дни, часы, минуты, секунды]. и предотвратите сбой кода должным образом.


TatsuSheva

Если я поставлю today = new Date(); когда я изменю время ПК, обратный отсчет также изменится, так что это не то, что я хочу...

TatsuSheva

я не хочу получать время ПК

Рейтинг:
2

Bob@work

Хорошо, я думаю, что понимаю вопрос-призыв к timeapi.org возвращает текущее время в соответствии с сервером timeapi. Затем вы используете это время, чтобы создать будущее время, один месяц в будущем в 7: 10 вечера. "Текущее" время (latime, today и todaystring) никогда не увеличивается после создания, поэтому обратный отсчет всегда сравнивает будущее время с неизменным текущим временем.

Чтобы избежать использования локальных пользовательских часов (которые можно изменить) для получения текущего времени, вы можете либо сделать новый ajax-вызов timeapi.org для доверенного текущего времени, понимая, что будет отставание, или увеличьте исходное текущее время локально в скрипте.

По моему опыту, приращение на клиентской машине может отставать от истинного времени, в зависимости от возможностей клиентской машины и вычислительной нагрузки, особенно в течение длительных периодов времени.

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

<html><head><title>countdown</title></head><body>

<span id="dday">days</span> d <span id="dhour">hours</span> h <span id="dmin">minutes</span> min <span id="dsec">seconds</span> sec
<div id="count2">id=count2</div>
<div class="numbers" id="dday" hidden=true >id=dday</div>
<hr />
<div id="debug"></div>
<script>
    var montharray = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
    var year;
    var month;
    var day;
    var hour = 19;
    var minute = 10;
    var tz = 0;
    var ladate;
    var today;

	 var bugbox;
	 
	 
    function myCallback(json) {

		bugbox=document.getElementById("debug");
		
		
		ladate = new Date(json.dateString);

        year = ladate.getFullYear();
        month = ladate.getMonth() + 1;
        day = ladate.getDate();
		  
		  bugbox.innerHTML+='<p>ladate= '+ladate+'</p>';
		  
		  bugbox.innerHTML+='<p>1. year, month, day, hour, minute= '+year+','+month+','+day+','+hour+','+minute+'</p>';
		  
        countdown(year, month, day, hour, minute);
    }

    function countdown(yr, m, d, hr, min) {
        theyear = yr;
        themonth = m;
        theday = d;
        thehour = hr;
        theminute = min;
		  
        today = ladate;
		  
		  today=new Date(yr,m-1,d,hr,min);
		  
		  bugbox.innerHTML+='<p>today= '+today+'</p>';
        var todayy = today.getYear();
        if (todayy < 1000) {
            todayy += 1900;
        }

        var todaym = today.getMonth();
        var todayd = today.getDate();
        var todayh = today.getHours();
        var todaymin = today.getMinutes();
        var todaysec = today.getSeconds();
        var todaystring1 = montharray[todaym-0] + " " + todayd + ", " + todayy + " " + todayh + ":" + todaymin + ":" + todaysec;
        var todaystring = Date.parse(todaystring1) + (tz * 1000 * 60 * 60);
        var futurestring1 = (montharray[m - 0] + " " + d + ", " + yr + " " + hr + ":" + min);
		  
		  bugbox.innerHTML+='<p>2. todaystring1= '+todaystring1+'</p>';
        bugbox.innerHTML+='<p>3. futurestring1= '+futurestring1+'</p>';
        
		  var futurestring = Date.parse(futurestring1) - (today.getTimezoneOffset() * (1000 * 60));
        var dd = futurestring - todaystring;
        var dday = Math.floor(dd / (60 * 60 * 1000 * 24) * 1);
        var dhour = Math.floor((dd % (60 * 60 * 1000 * 24)) / (60 * 60 * 1000) * 1);
        var dmin = Math.floor(((dd % (60 * 60 * 1000 * 24)) % (60 * 60 * 1000)) / (60 * 1000) * 1);
        var dsec = Math.floor((((dd % (60 * 60 * 1000 * 24)) % (60 * 60 * 1000)) % (60 * 1000)) / 1000 * 1);

        if (dday <= 0 && dhour <= 0 && dmin <= 0 && dsec <= 0) {
		  
		  bugbox.innerHTML+='<p>ERR: '+dday+','+dhour+','+dmin+','+dsec+'</p>';
            document.getElementById('count2').style.display = "inline";
            //document.getElementById('after').style.display = "none";

            document.getElementById('dday').style.display = "none";
            document.getElementById('dhour').style.display = "none";
            document.getElementById('dmin').style.display = "none";
            document.getElementById('dsec').style.display = "none";
            /***
				document.getElementById('days').style.display = "none";
            document.getElementById('hours').style.display = "none";
            document.getElementById('minutes').style.display = "none";
            document.getElementById('seconds').style.display = "none";
				***/
            return;
        } else {
            document.getElementById('count2').style.display = "none";
            document.getElementById('dday').innerHTML = dday;
            document.getElementById('dhour').innerHTML = dhour;
            document.getElementById('dmin').innerHTML = dmin;
            document.getElementById('dsec').innerHTML = dsec;
            setTimeout("countdown(theyear,themonth,theday,thehour,theminute)", 1000);
				
				bugbox.innerHTML+='<p>4. dday, dhour, dmin, dsec= '+dday+','+dhour+','+dmin+','+dsec+'</p>';
				
        }
    }
</script>
<script type="text/javascript" src="http://www.timeapi.org/utc/now.json?callback=myCallback"></script>

</body></html>


ZurdoDev

Пожалуйста, не публикуйте 3 решения. Просто отредактируйте свой существующий.

TatsuSheva

обратный отсчет идет не в реальном времени....

Bob@work

Правда, обратный отсчет - это все еще неизменная разница между временем, полученным из timeapi.org когда сценарий загружается (latime) и будущее время следующего месяца в 1910 году. Если вы не увеличите или не уменьшите что-то, чтобы изменить эту разницу во времени, отображаемый обратный отсчет не изменится.

TatsuSheva

Мне нужно это изменить....