Feb
2
Countdown JavaScript брояч с време от сървъра
at
00:32 by
nofearinc
Category: PHP
В процеса на работа ми се наложи да напиша един обратен таймер за отчитане на време при правене на електронен тест. Чудех се как да го реализирам, а не открих подходящо готово решение на проблема, в следствие на което си написах прост скрип за целта.
Изцяло сървърно решение не ми вършеше работа - всяка секунда трябва да се отброява намаляване на брояча с единица. Очевидно, за целта беше необходимо да се добави JavaScript. От друга страна, броячът за времето можеше да се изманипулира от часовника на потребителската машина, затова предпочетох да го взимам от сървъра.
Имаше и още едно условие: всеки въпрос е на отделна страница, т.е. броячът е персистентен между страниците.
Workaround
Компромисното ми решение бе следното: взима се текущото време от сървъра и се изчислява крайното време, след което трябва да свърши теста (примерно след 30мин, 90мин и т.н.). Извличат се час, минути и секунди, след което се подават на JavaScript. Той стартира таймер и на всяка секунда отмерва оставащото време в намаляващ ред.
Началният и крайният час се записват в сесията при инициализацията. След това единствено се отмерва diff - разликата между текущото време и крайното време, което са оставащите минути до края на теста.
Със сигурност има по-оптимално решение, но това работи в този случай. Ето и логиката в модела от даннитe: test.php (скелета на проектите ми приблизително описан тук):
date_default_timezone_set('GMT'); if(!isset($_SESSION['startTime'])) { $startTime = time(); $_SESSION['startTime'] = $startTime; // startDate is already used $_SESSION['endTime'] = time() + (1.5 * 60 * 60); } $diffDate = date("H:i:s", ($_SESSION['endTime'] - time())); $diff = ($_SESSION['endTime'] - time()); $hours = date('H', $diff); $mins = date('i', $diff); $secs = date('s', $diff);
Важно е в началото да се отбележи timezone, в противен случай се получава непредсказуем ефект в изпълнението на скрипта в различни часови зони. Затова съм го сетнал на GMT, да не мърда излишно.
Във view-то добавяме следното:
<script> var time = new Date(); time.setHours(<?php echo $hours ?>); time.setMinutes(<?php echo $mins ?>); time.setSeconds(<?php echo $secs ?>); </script> ... <div><script>countdown_clock(time.getHours(), time.getMinutes(), time.getSeconds());</script></div>
Създавам JavaScript таймер, на който задавам стойностите от времето на сървъра (оставащите часове, минути и секунди до края на теста). След това викам функцията, която ще отборява стойностите.
Таймерът дори не е необходим, тъй като JS функцията поема единствено числа и работи с часове, минути и секунди.
А ето и самият скрипт: countdown.js
function countdown_clock(hours, minutes, seconds) { html_code = '<div id="countdown"></div>'; document.write(html_code); if(seconds == 59) { seconds = 0; if(minutes == 59) { minutes = 0; hours++; } else { minutes++; } } else { seconds++; } countdown(hours, minutes, seconds); } function countdown(hours, minutes, seconds) { if(seconds == 0) { if(minutes == 0) { if(hours == 0) { document.getElementById('countdown').innerHTML = "0:00:00"; return; } else { hours--; minutes = 59; seconds = 59; } } else { minutes--; seconds = 59; } } else { seconds--; } if(minutes < 10) { minutes = "0" + minutes; } if(seconds < 10) { seconds = "0" + seconds; } document.getElementById('countdown').innerHTML = hours + ':' + minutes + ':' + seconds; setTimeout('countdown(' + hours + ',' + minutes + ',' + seconds + ');', 1000); }
Безподобния пост.
Related posts brought to you by Yet Another Related Posts Plugin.

















