Показать сообщение отдельно
  #1 (permalink)  
Старый 14.10.2011, 17:25
fiw fiw вне форума
Аспирант
Отправить личное сообщение для fiw Посмотреть профиль Найти все сообщения от fiw
 
Регистрация: 18.08.2011
Сообщений: 23

LiveTimer - Живой таймер обновлялка времени "Обновлено: около минуты назад".
Есть необходимость на сайт поставить скрипт который бы автоматом обновлял время добавления комментариев и тп. Как в любимых соц сетях.
Например: Добавлено: около минуты назад, потом по прошествии минуты само обновляется на добавлено 2 мин. назад.

Я взял готовый код из фейсбука ниже он

var LiveTimer = {
	restart: function (a) {
		this.serverTime = a;
		this.localStartTime = new Date().getTime() / 1000;
		this.updateTimeStamps();
	},
	updateTimeStamps: function () {
		LiveTimer.timestamps = DOM.scry(document.body, 'abbr.livetimestamp');
		LiveTimer.startLoop(20000);
	},
	addTimeStamps: function (a) {
		if (!a || !LiveTimer.timestamps) return;
		var c = DOM.scry(a, 'abbr.livetimestamp');
		for (var b = 0; b < c.length; ++b) LiveTimer.timestamps.push(c[b]);
		LiveTimer.startLoop(0);
	},
	startLoop: function (a) {
		this.stop();
		this.timeout = setTimeout(function () {
			LiveTimer.loop();
		}, a);
	},
	stop: function () {
		clearTimeout(this.timeout);
	},
	updateNode: function (a, b) {
		LiveTimer.updateNode = (ua.ie() < 7) ?
		function (c, d) {
			c.nextSibling.nodeValue = d;
		} : function (c, d) {
			c.firstChild.nodeValue = d;
		};
		LiveTimer.updateNode(a, b);
	},
	loop: function (d) {
		if (d) LiveTimer.updateTimeStamps();
		var c = Math.floor(new Date().getTime() / 1000 - LiveTimer.localStartTime);
		var a = -1;
		LiveTimer.timestamps && LiveTimer.timestamps.each(function (g) {
			var f = +new Date(g.getAttribute('data-date')) / 1000;
			var e = LiveTimer.renderRelativeTime(LiveTimer.serverTime + c, f);
			if (e.text) LiveTimer.updateNode(g, e.text);
			if (e.next != -1 && (e.next < a || a == -1)) a = e.next;
		});
		if (a != -1) {
			var b = Math.max(20000, a * 1000);
			LiveTimer.timeout = setTimeout(function () {
				LiveTimer.loop();
			}, b);
		}
	},
	renderRelativeTime: function (c, d) {
		var e = {
			text: "",
			next: -1
		};
		if (c - d > (12 * 3600) || (new Date(c * 1000).getDay() != new Date(d * 1000).getDay())) return e;
		var f = c - d,
			b = Math.floor(f / 60),
			a = Math.floor(b / 60);
		if (b < 1) {
			e.text = _tx("\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u043a\u0443\u043d\u0434 \u043d\u0430\u0437\u0430\u0434");
			e.next = 60 - f % 60;
			return e;
		}
		if (a < 1) {
			if (b == 1) {
				e.text = _tx("\u043e\u043a\u043e\u043b\u043e \u043c\u0438\u043d\u0443\u0442\u044b \u043d\u0430\u0437\u0430\u0434");
			} else e.text = _tx("{number} \u043c\u0438\u043d. \u043d\u0430\u0437\u0430\u0434", {
				number: b
			});
			e.next = 60 - f % 60;
			return e;
		}
		if (a != 11) e.next = 3600 - f % 3600;
		if (a == 1) {
			e.text = _tx("\u043e\u043a\u043e\u043b\u043e \u0447\u0430\u0441\u0430 \u043d\u0430\u0437\u0430\u0434");
			return e;
		}
		e.text = _tx("{number} \u0447. \u043d\u0430\u0437\u0430\u0434", {
			number: a
		});
		return e;
	}
};


К счастью механизм работы тут понятен.
Я поправил код, и получилось следующее
var LiveTimer: {
	startLoop: function(elem, time,start_update){
		this.timestamp = time;
		this.timeout = setTimeout(function(){
		LiveTimer.loop(elem);
		}, start_update);
	},
	loop: function(elem){
		var result = LiveTimer.renderTime(this.timestamp);
		if(result.text){
			DOM.extensions(elem,{innerHTML: result.text}); // тут я обнавляю результат на новую дату
		};
		var next_update = result.next;
		if(next_update != 0){
			next_update = Math.max(5000, next_update * 1000);
			this.timeout = setTimeout(function(){
			LiveTimer.loop(elem);
			}, next_update);
		};
	},
	renderTime: function(time){
		var now, passedTime, minutes, hours, days, item = {};
		this.servertime = new Number(ge('timestamp').innerHTML);
		passedTime = this.servertime - time;
		minutes = Math.floor(passedTime / 60);
		hours = Math.floor(minutes / 60);
		days = Math.floor(hours / 24);
			
		if(passedTime <= 10){
			item.text = 'Только что';
			item.next = 5; // следующее обновление таймера через 5 секунд
			return item;
		}else if(passedTime < 60){
			item.text = 'несколько секунд назад';
			item.next = 60;
			return item;
		}else if(minutes < 60){
			if (minutes < 2){
				item.text = 'около минуты назад';
			}else{
				item.text = minutes + ' мин. назад';
			};
			item.next = 60;
			return item;
		}else if(hours < 24){
			if (hours < 2){
				item.text = 'около часа назад';
			}else{
				item.text = hours+ ' ч. назад';
			};
			item.next = 3600;
			return item;
		}else if(days < 2){
			item.text = "вчера";
			item.next = 0;
			return item;
		}else{
			item.text = DTF(time); // Приводим время к обычному вормату типа: "12 января 2011 г. в 17:06"
			item.next = 0;
			return item;
		};
	}
}


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

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