Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #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;
		};
	}
}


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

Подскажите что я тут не учел, и пожалуйста поправьте код, наверняка такая штука будет полезна многим читателям форума.
Ответить с цитированием
  #2 (permalink)  
Старый 17.10.2011, 10:57
fiw fiw вне форума
Аспирант
Отправить личное сообщение для fiw Посмотреть профиль Найти все сообщения от fiw
 
Регистрация: 18.08.2011
Сообщений: 23

Ну что никто не может помочь?
Ответить с цитированием
  #3 (permalink)  
Старый 17.10.2011, 11:21
х.з
Посмотреть профиль Найти все сообщения от dmitriymar
 
Регистрация: 21.11.2010
Сообщений: 4,588

Сообщение от fiw
наверняка такая штука будет полезна многим читателям форума.
чем?
чтоб обновлять во всех ,нужно по всем им проходить. для этого им нужно дать идентификатор- имя или класс.

Последний раз редактировалось dmitriymar, 17.10.2011 в 11:23.
Ответить с цитированием
  #4 (permalink)  
Старый 18.10.2011, 01:36
Аватар для cyanidesign
Новичок на форуме
Отправить личное сообщение для cyanidesign Посмотреть профиль Найти все сообщения от cyanidesign
 
Регистрация: 13.10.2011
Сообщений: 4

Оформите ваш код в функцию-конструктор, и на каждый элемнет даты создавайте по экземпляру класса. Как это сделать можно найти здесь же, в статьях: http://javascript.ru/tutorial/object
Ответить с цитированием
  #5 (permalink)  
Старый 18.10.2011, 16:49
fiw fiw вне форума
Аспирант
Отправить личное сообщение для fiw Посмотреть профиль Найти все сообщения от fiw
 
Регистрация: 18.08.2011
Сообщений: 23

Сообщение от cyanidesign Посмотреть сообщение
Как это сделать можно найти здесь же, в статьях: http://javascript.ru/tutorial/object
Спасибо, я уже читал это, однако не доконца понял как это сделать, Хотелось бы увидеть пример по данному решению. Именно с датой.
Можно и упростить код, для наглядности...
Ответить с цитированием
  #6 (permalink)  
Старый 20.10.2011, 03:11
fiw fiw вне форума
Аспирант
Отправить личное сообщение для fiw Посмотреть профиль Найти все сообщения от fiw
 
Регистрация: 18.08.2011
Сообщений: 23

Дописал автоматический сбор всех таймштампов, которые надо будет обновлять.

var elemAbbr = geByClass('timestamp', document,'abrr');
for (var i = 0; i < elemAbbr.length; ++i){
	this.timestamps.push(elemAbbr[i].getAttribute('data-date'));
};

К сожалению, до сих пор не понял как всетаки идет назначение отдельных таймеров....
Без использования функции конструктора.
Ответить с цитированием
  #7 (permalink)  
Старый 24.10.2011, 05:09
fiw fiw вне форума
Аспирант
Отправить личное сообщение для fiw Посмотреть профиль Найти все сообщения от fiw
 
Регистрация: 18.08.2011
Сообщений: 23

Долго долго думал... и все таки огромное спасибо соц сети Вконтакте, за их красивый код.
Посмотрев внимательнее как это работает у них, сделал по аналогии, и все работает даже без каких либо функций конструкторов.
Ниже готовый рабочий кусок кода Loop.
Функция each довольно простая, думаю её сможете сами написать кому надо будет.
Её задача перебрать массив элементов, и к каждому вызвать колбэк.
loop: function(){
	var serverTime = id(timestamp).innerHTML;
	var next_update = -1;			
	each(geByClass('timestamp', document,'abrr'),
	function(k, elem) {
		if (!elem) return;
		var timestamp = intval(elem.getAttribute('data-date'));
		var result = LiveTimer.renderTime(serverTime, timestamp);
		if(result.text){
			DOM.extensions(elem,{innerHTML: result.text});
		};
		next_update = result.next;
		if(next_update != -1){
			next_update = Math.max(5000, next_update * 1000);
			this.timeout = setTimeout(function(){
				LiveTimer.loop(elem);
			}, next_update);
		};
	});
},
Ответить с цитированием
  #8 (permalink)  
Старый 24.10.2011, 17:43
Аватар для Riim
Рассеянный профессор
Отправить личное сообщение для Riim Посмотреть профиль Найти все сообщения от Riim
 
Регистрация: 06.04.2009
Сообщений: 2,379

Сообщение от fiw
item.text = 'около минуты назад';
}else{
item.text = minutes + ' мин. назад';
может тебе пригодится: link.
Ответить с цитированием
  #9 (permalink)  
Старый 25.10.2011, 01:56
fiw fiw вне форума
Аспирант
Отправить личное сообщение для fiw Посмотреть профиль Найти все сообщения от fiw
 
Регистрация: 18.08.2011
Сообщений: 23

Да спасибо )
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск