Skip to content

Commit 7891957

Browse files
author
Michael Weibel
committed
Implemented only one Interval on a page.
This commit will fix jquery.timeago's issue to have an interval for each timeago element on a page. By doing this it also removes destroyed elements automatically. As such, this commit fixes rmm5t#96 and rmm5t#90.
1 parent 4dad17f commit 7891957

File tree

1 file changed

+72
-10
lines changed

1 file changed

+72
-10
lines changed

jquery.timeago.js

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
44
*
55
* @name timeago
6-
* @version 1.1.0
7-
* @requires jQuery v1.2.3+
6+
* @version 1.2.0
7+
* @requires jQuery v1.7.0+
88
* @author Ryan McGeary
99
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
1010
*
@@ -36,9 +36,19 @@
3636
};
3737
var $t = $.timeago;
3838

39+
// destroyed event handler comes from:
40+
// http://stackoverflow.com/questions/2200494/jquery-trigger-event-when-an-element-is-removed-from-the-dom/10172676#10172676
41+
jQuery.event.special.timeagodestroyed = {
42+
remove: function(o) {
43+
if (o.handler) {
44+
o.handler($(this));
45+
}
46+
}
47+
};
48+
3949
$.extend($.timeago, {
4050
settings: {
41-
refreshMillis: 60000,
51+
refreshMillis: 6000,
4252
allowFuture: false,
4353
localeTitle: false,
4454
strings: {
@@ -115,6 +125,55 @@
115125
isTime: function(elem) {
116126
// jQuery's `is()` doesn't play well with HTML5 in IE
117127
return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
128+
},
129+
130+
elements: [],
131+
132+
initInterval: function() {
133+
if (!$(document).data('timeago_interval')) {
134+
var intervalId = setInterval(function() {
135+
for (var i = 0, elLength = $t.elements.length; i < elLength; i++) {
136+
$t.elements[i].trigger('timeago:update');
137+
}
138+
}, $t.settings.refreshMillis);
139+
$(document).data('timeago_interval', intervalId);
140+
}
141+
},
142+
143+
removeInterval: function() {
144+
clearInterval($(document).data('timeago_interval'));
145+
for (var i = 0, elLength = $t.elements.length; i < elLength; i++) {
146+
$t.elements[i].off('timeago:update');
147+
}
148+
$t.elements = [];
149+
},
150+
151+
updateHandler: function(evt) {
152+
refresh.apply(this);
153+
},
154+
155+
addElement: function(elem) {
156+
var index = $t.elements.length,
157+
$elem = $(elem);
158+
// prevent double add.
159+
if($elem.data('timeagoIndex') !== undefined) {
160+
return;
161+
}
162+
refresh.apply(elem);
163+
$elem.data('timeagoIndex', index);
164+
$t.elements.push($elem);
165+
$elem.on('timeago:update', $t.updateHandler);
166+
$elem.on('timeagodestroyed', $t.removeElement);
167+
},
168+
removeElement: function(elem) {
169+
var $elem = $(elem),
170+
elemIndex = $elem.data('timeagoIndex');
171+
$(elem).off('timeago:update');
172+
$t.elements.splice(elemIndex, 1);
173+
// update indexes of the remaining elements after the index
174+
for (var i = elemIndex, elLength = $t.elements.length; i < elLength; i++) {
175+
$t.elements[i].data('timeagoIndex', i);
176+
}
118177
}
119178
});
120179

@@ -123,12 +182,13 @@
123182
// functions are called with context of a single element
124183
var functions = {
125184
init: function(){
126-
var refresh_el = $.proxy(refresh, this);
127-
refresh_el();
128-
var $s = $t.settings;
129-
if ($s.refreshMillis > 0) {
130-
setInterval(refresh_el, $s.refreshMillis);
131-
}
185+
$t.addElement(this);
186+
},
187+
remove: function() {
188+
$t.removeElement(this);
189+
},
190+
removeInterval: function() {
191+
$t.removeInterval();
132192
},
133193
update: function(time){
134194
$(this).data('timeago', { datetime: $t.parse(time) });
@@ -137,6 +197,8 @@
137197
};
138198

139199
$.fn.timeago = function(action, options) {
200+
$t.initInterval();
201+
140202
var fn = action ? functions[action] : functions.init;
141203
if(!fn){
142204
throw new Error("Unknown function name '"+ action +"' for timeago");
@@ -162,7 +224,7 @@
162224
element.data("timeago", { datetime: $t.datetime(element) });
163225
var text = $.trim(element.text());
164226
if ($t.settings.localeTitle) {
165-
element.attr("title", element.data('timeago').datetime.toLocaleString())
227+
element.attr("title", element.data('timeago').datetime.toLocaleString());
166228
} else if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
167229
element.attr("title", text);
168230
}

0 commit comments

Comments
 (0)