-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathios6fix.js
110 lines (108 loc) · 3.59 KB
/
ios6fix.js
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
(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: [email protected]
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;
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));