Added timers.js
This commit is contained in:
parent
6f0f557bc6
commit
57ace1a74e
1 changed files with 132 additions and 0 deletions
132
timers.js
Normal file
132
timers.js
Normal file
|
@ -0,0 +1,132 @@
|
|||
(function (window) {
|
||||
|
||||
// This library re-implements setTimeout, setInterval, clearTimeout, clearInterval for iOS6.
|
||||
// iOS6 suffers from a bug that kills timers that are created while a page is scrolling.
|
||||
// This library fixes that problem by recreating timers after scrolling finishes (with interval correction).
|
||||
// This code is free to use by anyone (MIT, blabla).
|
||||
// Author: rkorving@wizcorp.jp
|
||||
|
||||
var timeouts = {};
|
||||
var intervals = {};
|
||||
var orgSetTimeout = window.setTimeout;
|
||||
var orgSetInterval = window.setInterval;
|
||||
var orgClearTimeout = window.clearTimeout;
|
||||
var orgClearInterval = window.clearInterval;
|
||||
|
||||
|
||||
function createTimer(set, map, args) {
|
||||
var id, cb = args[0], repeat = (set === orgSetInterval);
|
||||
|
||||
function callback() {
|
||||
if (cb) {
|
||||
cb.apply(window, arguments);
|
||||
|
||||
if (!repeat) {
|
||||
delete map[id];
|
||||
cb = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
args[0] = callback;
|
||||
|
||||
id = set.apply(window, args);
|
||||
|
||||
map[id] = { args: args, created: Date.now(), cb: cb, id: id };
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
function resetTimer(set, clear, map, virtualId, correctInterval) {
|
||||
var timer = map[virtualId];
|
||||
|
||||
if (!timer) {
|
||||
return;
|
||||
}
|
||||
|
||||
var repeat = (set === orgSetInterval);
|
||||
|
||||
// cleanup
|
||||
|
||||
clear(timer.id);
|
||||
|
||||
// reduce the interval (arg 1 in the args array)
|
||||
|
||||
if (!repeat) {
|
||||
var interval = timer.args[1];
|
||||
|
||||
var reduction = Date.now() - timer.created;
|
||||
if (reduction < 0) {
|
||||
reduction = 0;
|
||||
}
|
||||
|
||||
interval -= reduction;
|
||||
if (interval < 0) {
|
||||
interval = 0;
|
||||
}
|
||||
|
||||
timer.args[1] = interval;
|
||||
}
|
||||
|
||||
// recreate
|
||||
|
||||
function callback() {
|
||||
if (timer.cb) {
|
||||
timer.cb.apply(window, arguments);
|
||||
if (!repeat) {
|
||||
delete map[virtualId];
|
||||
timer.cb = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
timer.args[0] = callback;
|
||||
timer.created = Date.now();
|
||||
timer.id = set.apply(window, timer.args);
|
||||
}
|
||||
|
||||
|
||||
window.setTimeout = function () {
|
||||
return createTimer(orgSetTimeout, timeouts, arguments);
|
||||
};
|
||||
|
||||
|
||||
window.setInterval = function () {
|
||||
return createTimer(orgSetInterval, intervals, arguments);
|
||||
};
|
||||
|
||||
window.clearTimeout = function (id) {
|
||||
var timer = timeouts[id];
|
||||
|
||||
if (timer) {
|
||||
delete timeouts[id];
|
||||
orgClearTimeout(timer.id);
|
||||
}
|
||||
};
|
||||
|
||||
window.clearInterval = function (id) {
|
||||
var timer = intervals[id];
|
||||
|
||||
if (timer) {
|
||||
delete intervals[id];
|
||||
orgClearInterval(timer.id);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', function () {
|
||||
// recreate the timers using adjusted intervals
|
||||
// we cannot know how long the scroll-freeze lasted, so we cannot take that into account
|
||||
|
||||
var virtualId;
|
||||
|
||||
for (virtualId in timeouts) {
|
||||
resetTimer(orgSetTimeout, orgClearTimeout, timeouts, virtualId);
|
||||
}
|
||||
|
||||
for (virtualId in intervals) {
|
||||
resetTimer(orgSetInterval, orgClearInterval, intervals, virtualId);
|
||||
}
|
||||
});
|
||||
|
||||
}(window));
|
Reference in a new issue