public
Last active — forked from ronkorving/ios6-timers.js

iOS6 webkit timer bug workaround

  • Download Gist
ios6-timers.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
(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).
// Original Author: rkorving@wizcorp.jp
var timeouts = {};
var intervals = {};
var orgSetTimeout = window.setTimeout;
var orgSetInterval = window.setInterval;
var orgClearTimeout = window.clearTimeout;
var orgClearInterval = window.clearInterval;
// To prevent errors if loaded on older IE.
if (!window.addEventListener) return false;
// This fix needs only for iOS 6.0 or 6.0.1, continue process if the version matched.
if (!navigator.userAgent.match(/OS\s6_0/)) return false;
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);
}
};
//check and add listener on the top window if loaded on frameset/iframe
var win = window;
while (win.location != win.parent.location) {
win = win.parent;
}
win.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));

frameに組み込まれている場合にscrollイベントを最上部のwindowに貼り付けるように設定

can somebody tell where i input the source code?
I have read that the sourcecode must be copy into the jquery.js file but if i do this task the problems are not changed

All you need to work this fix is just load the file on the head with script tag.
This fix may affect other non-bug devices, though, load & append it
if (iOS6) { // check iOS6 with your custom flag
$('head').append('');
}

I have checked this bug on iOS 6.0.1, but the problem is still remaining.

This worked for me! touchswipe froze when resizing (scrolling/zooming) a page on iphone4 with iOS6. I saved this code as a js file and included it in my page in which i use a SudoSlider with TouchSwipe. Now i can resize and scroll the page and the swiping on the slider keeps working.

Ur a hero. Thank u

I seem to be getting this error in console:
TypeError: 'undefined' is not a function (evaluating 'timer.cb.apply(window, arguments)')

any ideas?

#edit

nasty work around with browser sniffing wrap the above in:
if((navigator.userAgent.match(/(iPhone|iPod|iPad)/i))) {
}

Apparently, Apple fixed this problem on iOS 6.1 released today.
You can check whether fixed or not by the page below

https://gist.github.com/4661261

Hi.. I have added the fix.js in my header and issue seems to be fixed. But my images are inside a link (anchor tag), while clicking the image, its not redirecting. Just showing the loading icon and nothing happens after that. Please, need help on this :(

Added useragent check in order to fix the issue only on iOS 6 or 6.0.1.

Hi.. Thanks for your valuable help and sorry for the late response from my end. I have updated the code, but still its not working for me. Redirection is not working. I am using iOS 6.0.1. Same issue in android 4.0.4 also. Please need help :(

@sarathrajan HI, I think you should post your comment on https://github.com/malsup/cycle2/issues this project's issues section, not here.

This is my own gist post, and have no relation with malsup/cycle2 project.
And, I guess your problem is not caused my gist. I hope you could find the answer there :)

Hi kTmnh, Thanks for your response. But I am getting this link issue only after adding this ios6-timers.js. So can you suggest me a solution for this. Thanks in advance for all your help :)

@sarathrajan I see. Is there anywhere I can review your code? Please let me know the page you have error you mention, I think I could help you.

@kTmnh, My site is not yet live. So unfortunately cant review my code now. What I am having is a slideshow of images. I am using cycle 2 for this slideshow. All my images are given links to their respective pages. But I am getting issue in the slideshow after a 'L' shaped swipe. And I added this js to fix this. It worked fine after adding ur js. But unfortunately when i click the image, its not redirecting to its page. I am in a critical situation :( .If its not working, i need to use some other plugin for this slideshow. :( But I would like to use the awesome cycle 2 itself. Is there any way to fix this issue?

Hi kTmnh, Can you give me a solution for this please :(

Not able to fix this issue.. :( I am planning to use another plugin. :(

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.