Непрерывный таймер

Статус
В этой теме нельзя размещать новые ответы.
зачем сервер
сохраняеш в куке время старта таймера ну и каждую секунду (период) в куке обновляеш сколько натикало
а после переоткрытия страницы
сравниваеш даты что хранится в куке с тем сколько сейчас времени у пользователя
получаеш разницу и добавляеш к таймеру в куке(отнимаеш)
запускаеш таймер
2. Пишеш в куки (чистятся куки легко в любом броузере)
Если вопрос в маштабах школы, предприятия на 10 человек, то вариант катит. А когда вопрос в комерциалиазации, то оплошностей не должно быть.
Например, сдает какой-то читер тесты приема на работу, обрыл весь инет наштамповал ответы, очистил куки в ФФ подождал еще 10 минут сложил тест который не все профи за пол часа делают и докажи ему что он не дурак!
 
А как тогда реализован таймер в микротодо от тороза? Там именно так, как мне нужно.. Просто в коде не могу разобраться
 
А как тогда реализован таймер в микротодо от тороза? Там именно так, как мне нужно.. Просто в коде не могу разобраться
Там то как раз в броузер пишутся куки
Вот код
Код:
<script>
document.createElement('header');
document.createElement('section');
document.createElement('footer');
var cookieToDo = "mToDo";
var cookieExToDo = "mExToDo";
var cookieExToDoEnd = "mExToDoEnd";
var cookieTimer = "mToDoTime";
var cookieTimerPause = "mToDoTimePause";
var todo = new Array();
var extodo = new Array();
var extodoend = new Array();
var curTime = parseInt( new Date().getTime() / 1000, 10 );
var pauseTime = curTime;
var isTime = false;
var isTimePause = false;
var tMonth = 1000 * 60 * 60 * 24 * 31;
var tWeek = 1000 * 60 * 60 * 24 * 7;
var defaultMess = 'Что нужно делать?';
var value, i, index, time;
var isIE = (String(typeof(document.all)) != "undefined"); // для проверки ie 
function trim(str) {
 return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}
function plural(n, f1, f2, f5) {
 n = Math.abs(n) % 100;
 i = n % 10;
 if (n > 10 && n < 20) return f5;
 if (i > 1 && i < 5) return f2;
 if (i == 1) return f1;
 return f5;
}
function setCookie( name, value, expire ) {
 time = new Date();
 time.setTime( time.getTime() + expire );
 document.cookie = name + "=" + value + "; expires=" + time.toGMTString();
 return true;
}
function getCookie( name ) {
 var cSIndex = document.cookie.indexOf( name );
 if (cSIndex == -1) return false;
 cSIndex = document.cookie.indexOf( name + "=" )
 if (cSIndex == -1) return false;
 var cEIndex = document.cookie.indexOf( ";", cSIndex + ( name + "=" ).length );
 if (cEIndex == -1) cEIndex = document.cookie.length;
 return document.cookie.substring( cSIndex + ( name + "=" ).length, cEIndex );
}
function delCookie( name ) {
 if ( getCookie( name )) 
  document.cookie = name + "=; expires=Thu, 01-Jan-70 00:00:01 GMT";
}
function prepareCookie( name, value ) {
 var ret = new Array();
 for ( i = 0; i < value.length; ++i ) {
  ret.push( escape( value[i] ));
 }
 ret = ret.join( "&" );
 if ( ( name + "=" + value ).length >= 4086 ) 
  return false;
 return setCookie( name, ret, tMonth );
}
function clear() {
 isTime = false;
 isTimePause = false;
 curTime = 0;
 pauseTime = curTime;
 todo = new Array();
 extodo = new Array();
 extodoend = new Array();
 delCookie( cookieToDo );
 delCookie( cookieExToDo );
 delCookie( cookieExToDoEnd );
 delCookie( cookieTimer );
 delCookie( cookieTimerPause );
 $("newtodo").className = "hidden";
 $tag("footer").className = "hidden";
 return true;
}
function $(v) {return document.getElementById(v)}
function $tag(v) {return document.getElementsByTagName(v)[0]}
function $name(v) {return document.getElementsByName(v)}
function addToDo( value, arr, cookie ) {
 arr.push( value );
 if ( prepareCookie( cookie, arr )) { 
  return true;
 } else { 
  arr.pop();
  alert( "Слишком много записей. \nНадо бы что-то удалить." );
  return false;
 }
}
function delToDo( index, arr, cookie ) {
 arr.splice( index, 1 );
 prepareCookie( cookie, arr );
 if ( ! todo.length && ! extodo.length ) {
  clear();
 }
 return false;
}
function toToDo( index ) {
 if ( addToDo( extodo[index], todo, cookieToDo ) ) {
  extodo.splice( index, 1 );
  extodoend.splice( index, 1 );
  prepareCookie( cookieExToDo, extodo );
  prepareCookie( cookieExToDoEnd, extodoend );
 }
 if ( ! isTime ) {
  isTime = true;
 }
 if ( ! extodo.length ) {
  extodo = new Array();
  extodoend = new Array();
  delCookie( cookieExToDo );
  delCookie( cookieExToDoEnd );
 }
 refresh();
 return false;
}
function toExToDo( index ) {
 if ( addToDo( todo[index], extodo, cookieExToDo ) ) {
  time = parseInt( new Date().getTime() / 1000, 10 );
  time -= curTime;
  var min = parseInt( time / 60 % 60, 10);
  var hour = parseInt( time / 3600, 10);
  value = ( hour > 0 ? hour + " ч. " : "" ) + "" + min + " мин.";
  extodoend.push( value );
  prepareCookie( cookieExToDoEnd, extodoend );
  todo.splice( index, 1 );
  prepareCookie( cookieToDo, todo );
  if ( todo.length <= 1 && getCookie( "footer" ) != 'hidden' ) {
   $tag("footer").className = "";
  }
  if ( ! extodo.length ) {
   todo = new Array();
   delCookie( cookieToDo );
  }
 }
 refresh();
 return false;
}
function timerPause() {
 if ( ! todo.length && extodo.length && ! isTimePause ) {
  isTimePause = true;
  pauseTime = parseInt( new Date().getTime() / 1000, 10 );
  setCookie( cookieTimerPause, pauseTime, tMonth );
  return true;
 }
 return false;
}
function timerStart() {
 //alert(todo.length + '\n' + isTimePause);
 if ( isTimePause && todo.length ) {
  isTime = true;
  isTimePause = false;
  var tTime = parseInt( new Date().getTime() / 1000, 10 );
  curTime += ( tTime - pauseTime );
  setCookie( cookieTimer, curTime, tMonth );
  delCookie( cookieTimerPause );
  return true;
 }
 return false;
}
function timer() {
 var min = 0;
 var hour = 0;
 var sec = 0;
 if ( isTime && ! isTimePause ) {
  time = parseInt( new Date().getTime() / 1000, 10 );
  time -= curTime;
  min = parseInt( time / 60 % 60, 10);
  hour = parseInt( time / 3600, 10);
  sec = parseInt( time % 60, 10);
  hour = hour > 0 ? hour + " " + plural( hour, "час", "часа", "часов" ) : "";
  min = min > 0 ? min + " " + plural( min, "минута", "минуты", "минут" ) : "";
  value = "<span>" + hour + " " + min + "</span> " + sec;
 } else if ( isTimePause ) {
  time = pauseTime - curTime;
  min = parseInt( time / 60 % 60, 10);
  hour = parseInt( time / 3600, 10);
  sec = parseInt( time % 60, 10);
  hour = hour > 0 ? hour + " " + plural( hour, "час", "часа", "часов" ) : "";
  min = min > 0 ? min + " " + plural( min, "минута", "минуты", "минут" ) : "";
  value = "<span>" + hour + " " + min + "</span> " + sec;
 } else {
  value = "<span></span>";
 }
 $("timer").innerHTML = value;
 setTimeout( "timer()", 1000 );
}
function add() {
 value = $("new").value;
 if ( value.length < 1 ) {
  return false;
 }
 if ( value == defaultMess ) {
  return false;
 }
 value = value.replace( /</, "&lt;" );
 value = value.replace( />/, "&gt;" );
 if ( addToDo( value, todo, cookieToDo )) {
  $("new").value = "";
 }
 if ( ! isTime ) {
  isTime = true;
  isTimePause = false;
  curTime = parseInt( new Date().getTime() / 1000, 10 );
  setCookie( cookieTimer, curTime, 1000 * 60 * 60 * 24 * 31 );
  $("newtodo").className = "";
 } 
 return true;
}
function delTD( index ) {
 delToDo( index, todo, cookieToDo );
 refresh();
 return true;
}
function delETD( index ) {
 delToDo( index, extodo, cookieExToDo );
 refresh();
 return true;
}
function refresh() {
 timerStart();
 timerPause();
 var list = "";
 for ( i = 0; i < todo.length; ++i ) {
  list += '<li><label><input type="checkbox" onclick="toExToDo(' + i + ');return false;" /> ' + todo[i] + ' <a href="#" title="Удалить" onclick="delTD(' + i + ');return false;">&times;</a></label></li>';
 }
 for ( i = 0; i < extodo.length; ++i ) {
  list += '<li class="OK"><label><input type="checkbox" checked onclick="toToDo(' + i + ');return false;"/> ' + extodo[i] + ' <a href="#" title="Удалить" onclick="delETD(' + i + ');return false;">&times;</a> ' + extodoend[i] + '</label></li>';
 }
 $tag("ul").innerHTML = list;
}
//     добавление сразу нескольких заданий через textarea,  
//    \n - как разделитель
	function multiadd() {
		value = $("newlist").value.replace(defaultMess,'');
		if ( value.length < 1 ) {
			return false;
		}
		value = value.replace( /</, "&lt;" );
		value = value.replace( />/, "&gt;" );
		var tasks_arr = value.split('\n', 999);
		value='x';
		for( i=0; i < tasks_arr.length; i++) {
			if(trim(tasks_arr[i])!='') {
				todo.push( tasks_arr[i] );
				value = value+'&'+escape(tasks_arr[i]);
			}
		}
		value=value.replace('x&','');
		time = new Date();
		time.setTime( time.getTime() + tMonth );
		if(getCookie(cookieToDo) != false){
			value = getCookie(cookieToDo) + '&' + value;
		}
		document.cookie = cookieToDo + "=" + value + "; expires=" + time.toGMTString();
		if ( ! isTime ) {
			isTime = true;
			isTimePause = false;
			curTime = parseInt( new Date().getTime() / 1000, 10 );
			setCookie( cookieTimer, curTime, 1000 * 60 * 60 * 24 * 31 );
			$("newtodo").className = "";
		}
		$("newlist").value='';
		refresh();
		return true;
	}
function init() {
 var is_chrome = false;
 if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
  is_chrome = true;
 }
 if( getCookie( "testCookie" ) != "testCookie" ) {
  var testCookie = new String( window.location.href ).split("?")[1];
  if ( testCookie != "testCookie" ) {
   setCookie( "testCookie", "testCookie", 1000 * 60 * 60 * 24 * 31 );
   window.location.href = "?testCookie";
   exit;
  } else {
   if ( is_chrome && window.location.href.substr( 0, 4 ) != 'http' ) {
    $("chrome").className = "ahtung";
   }
   else {
    $("nocookie").className = "ahtung";
   }
  }
 }
 value = getCookie( cookieToDo );
 if ( value ) {
  todo = value.split( "&" );
  for ( i = 0; i < todo.length; ++i )
   todo[i] = unescape(todo[i]);
 }
 value = getCookie( cookieExToDo );
 if ( value ) {
  extodo = value.split( "&" );
  for ( i = 0; i < extodo.length; ++i )
   extodo[i] = unescape(extodo[i]);
 }
 value = getCookie( cookieExToDoEnd );
 if ( value ) {
  extodoend = value.split( "&" );
  for ( i = 0; i < extodoend.length; ++i )
   extodoend[i] = unescape(extodoend[i]);
 }
	// новый список
	$("newtodo").onclick = function() {
		clear();
		refresh();
		return false;
	}
	// удаляем задание
	$("del").onclick = function() {
		$tag("footer").className = "hidden";
		setCookie( "footer", "hidden", tWeek );
		return false;
	};
	// убираем стандартный текст из textarea при фокусе
	$("newlist").onfocus = function() {
		if ( this.value == defaultMess ){
		   this.value = "";
		 }
	};
	// отправка формы добавления нескольких заданий
	$("multiadd").onsubmit = function() {
		multiadd();
		return false;
	}
	// клик по Enter, кнопки отправки
	$("multiaddtodo").onclick = function () {
		multiadd();
		return false;
	};
	// отправка данных textarea по  Enter ctrl+enter ctrl+v
	$("newlist").onkeydown = function(event) {
		// ctrl+enter
		if((event.ctrlKey) && ((event.keyCode==10)||(event.keyCode==13))) {
			multiadd();
			return false;
		}
		// ctrl+v
		if((event.ctrlKey) && (event.keyCode==86)) {
				setTimeout(function() {if($("newlist").value.indexOf("\n")!=-1) {multiadd();} }, 200)
		}
		// enter
		if(event.keyCode==10 || event.keyCode==13) {
			multiadd();
			return false;
		}
	};
	// отправка при изменение содержимого(причём при добавлении несколькиз строк) и ухода фокуса с textarea
	$("newlist").onchange = function(event) {
		if(this.value.replace(' ', '')!='' && this.value.indexOf("\n")!=-1) {
			multiadd();
			return false;
		}
	};
	// при уходе фокуса с textarea  ставим стандартный текст
	$("newlist").onblur = function() {
		if($("newlist").value=='') {this.value = defaultMess;}
	};
 if ( ! todo.length && ! extodo.length ) {
 }
 if ( todo.length || extodo.length ) {
  isTime = true;
  curTime = parseInt( getCookie( cookieTimer ) , 10);
  pauseTime = parseInt( getCookie( cookieTimerPause ) , 10 );
  if ( pauseTime && ! todo.length ) {
   isTimePause = true;
  }
  $("newtodo").className = "";
 }
 if ( ! curTime ) {
  curTime = parseInt( new Date().getTime() / 1000, 10 );
 }
 $("newlist").value = defaultMess;
 refresh();
 timer();
}
</script>
Суть такова в броузер принимается куки с названием mToDoTime и значением setCookie( cookieTimer, curTime, tMonth );
путем експеримента выяснилось если подправить куки то легко можно менять значения таймера временем (я реально изменил время с 5 минут на 1 минуту, поскольку запускал в разных броузерах и во втором глянул какое значение прописано в куки ). Осталось только разглядеть поближе какая функция отвечает за генерацию времени: var curTime = parseInt( new Date().getTime() / 1000, 10 );


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


Неправильный способ. Раз в 10 секунд делать из JavaScript запрос на сервер для проверки, сколько прошло вермени от начала отсчета. Этот метод не работает, если на сайте одновременно находится очень большое количество пользователей, т.к. нагрузка на сервер растет слишком быстро. Кроме того, потребление трафика пользователем также оказывается крайне высоким.
Правильный способ. Устанавливать постоянное и длительное соединение с сервером, ожидая поступления данных (нужного временного отсчета) через него. Если сообщений нет, соединение просто держится открытым на протяжение нескольких минут. Если соединение по каким-либо причинам закрылось, оно вновь открывается. В итоге и трафика потребляется мало, и нагрузка на сервер оказывается невелика. Так работает GMail, Мой Круг и т. д., и именно на этом принципе построен dklab_multiplexor.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху