Skip to content

Instantly share code, notes, and snippets.

@honmaaax
Forked from ronkorving/ios6-timers.js
Created October 16, 2012 03:08
Show Gist options
  • Select an option

  • Save honmaaax/3897054 to your computer and use it in GitHub Desktop.

Select an option

Save honmaaax/3897054 to your computer and use it in GitHub Desktop.
iOS6 webkit timer bug workaround
(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 timers = {};
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];
function callback() {
if (cb) {
delete map[id];
cb.apply(window, arguments);
cb = null;
}
}
args[0] = callback;
id = set.apply(window, args);
map[id] = { args: args, created: Date.now(), cb: cb };
return id;
}
function resetTimers(set, clear, oldMap, newMap, correctInterval) {
for (var id in oldMap) {
var timer = oldMap[id];
// cleanup
clear(id);
// reduce the interval (arg 1 in the args array)
var interval = timer.args[1];
if (correctInterval) {
var reduction = Date.now() - timer.created;
if (reduction < 0) {
reduction = 0;
}
interval -= reduction;
if (interval < 0) {
interval = 0;
}
}
timer.args[0] = timer.cb;
timer.args[1] = interval;
// recreate
createTimer(set, newMap, timer.args);
}
}
window.setTimeout = function () {
return createTimer(orgSetTimeout, timers, arguments);
};
window.setInterval = function () {
return createTimer(orgSetInterval, intervals, arguments);
};
window.clearTimeout = function (id) {
delete timers[id];
orgClearTimeout(id);
};
window.clearInterval = function (id) {
delete intervals[id];
orgClearInterval(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 oldTimers = timers;
var oldIntervals = intervals;
timers = {};
intervals = {};
resetTimers(orgSetTimeout, orgClearTimeout, oldTimers, timers, true);
resetTimers(orgSetInterval, orgClearInterval, oldIntervals, intervals, false);
});
}(window));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment