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; }; } } Но мой код имеет один недостаток, он способен работать, следить и обновлять только один элемент с датой. Если появляется второй, и запускает скрипт, то он как то влияет на первый более ранний элемент. Подскажите что я тут не учел, и пожалуйста поправьте код, наверняка такая штука будет полезна многим читателям форума. |
Ну что никто не может помочь?
|
Цитата:
чтоб обновлять во всех ,нужно по всем им проходить. для этого им нужно дать идентификатор- имя или класс. |
Оформите ваш код в функцию-конструктор, и на каждый элемнет даты создавайте по экземпляру класса. Как это сделать можно найти здесь же, в статьях: http://javascript.ru/tutorial/object
|
Цитата:
Можно и упростить код, для наглядности... |
Дописал автоматический сбор всех таймштампов, которые надо будет обновлять.
var elemAbbr = geByClass('timestamp', document,'abrr'); for (var i = 0; i < elemAbbr.length; ++i){ this.timestamps.push(elemAbbr[i].getAttribute('data-date')); }; К сожалению, до сих пор не понял как всетаки идет назначение отдельных таймеров.... Без использования функции конструктора. |
Долго долго думал... и все таки огромное спасибо соц сети Вконтакте, за их красивый код.
Посмотрев внимательнее как это работает у них, сделал по аналогии, и все работает даже без каких либо функций конструкторов. Ниже готовый рабочий кусок кода 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); }; }); }, |
Цитата:
|
Да спасибо )
|
Часовой пояс GMT +3, время: 05:06. |