forked from jgthms/css-reference
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
130 lines (112 loc) · 4.23 KB
/
Copy pathindex.js
File metadata and controls
130 lines (112 loc) · 4.23 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
document.body.classList.add('has-js');
document.addEventListener('DOMContentLoaded', function() {
// dynamically show examples
var $exampleOutputs = [].slice.call(document.querySelectorAll('.example-output'));
var $exampleBrowsers = [].slice.call(document.querySelectorAll('.example-browser'));
var $exampleWrappers = [].slice.call(document.querySelectorAll('.example'));
var propPositions = $exampleBrowsers.map(function($exampleBrowser, ix) {
var offsetProps = getOffset($exampleBrowser);
var $wrapper = $exampleWrappers[ix];
return {
displayed: false,
$exampleBrowser: $exampleBrowser,
$exampleOutput: $exampleOutputs[ix],
offsetTop: offsetProps.top,
$wrapper: $wrapper,
originalWrapperHeight: getHeight($wrapper)
};
});
startWatching();
// Logo
var $logo = document.getElementById('logo');
$logo.addEventListener('click', function(event) {
event.preventDefault();
history.replaceState('', document.title, ' ');
window.scrollTo(0,0);
});
// Hashes
var $hashes = document.querySelectorAll('.hash, .menu-list-ul li a');
Array.prototype.forEach.call($hashes, function($el) {
$el.addEventListener('click', function(event) {
event.preventDefault();
var propertyName = $el.dataset.propertyName;
var $target = document.getElementById($el.dataset.propertyName);
history.replaceState('', document.title, '#' + propertyName);
if ($target) {
$target.scrollIntoView();
}
});
});
// Helpers
function startWatching() {
var doc = document.documentElement;
var prevTop = 0;
var prevWindowHeight = 0;
var scrollMargin = 200;
window.requestAnimationFrame(function loop() {
var top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
var windowHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
// if we've scrolled, clicked on an anchor, or made the window bigger
if (top !== prevTop || windowHeight > prevWindowHeight) {
prevWindowHeight = windowHeight;
prevTop = top;
var aboveTheWindow = top - scrollMargin;
var belowTheWindow = top + windowHeight + scrollMargin;
showExamples(propPositions, aboveTheWindow, belowTheWindow);
}
setTimeout(window.requestAnimationFrame.bind(window, loop), 100);
});
}
function showExamples(propPositions, aboveTheWindow, belowTheWindow) {
var i = 0;
while (++i < propPositions.length) {
// if we've already show this example, or we're before the viewing window
if (
propPositions[i].displayed ||
propPositions[i].offsetTop < aboveTheWindow
) {
continue;
}
// PERF: because the elements are effectively sorted by offsetTop ASC
// we know that once we are higher than the bottom range
// we no longer need to check the remainder
if (propPositions[i].offsetTop > belowTheWindow) {
return;
}
// we now know we're in the loading window
propPositions[i].displayed = true;
propPositions[i].$exampleOutput.style.display = 'block';
var newWrapperHeight = getHeight(propPositions[i].$wrapper);
addHeightToRest(propPositions, newWrapperHeight - propPositions[i].originalWrapperHeight, i);
}
}
function addHeightToRest(positions, height, ix) {
for (var i = ix + 1; i < positions.length; i++) {
positions[i].offsetTop += height;
}
}
function isWindow(obj) {
return obj != null && obj === obj.window;
}
function getWindow($element) {
return isWindow($element) ? $element : $element.nodeType === 9 && $element.defaultView;
}
function getOffset($element) {
var win;
var box = { top: 0, left: 0 };
var doc = $element && $element.ownerDocument;
var docElem = doc.documentElement;
if (typeof $element.getBoundingClientRect !== typeof undefined) {
box = $element.getBoundingClientRect();
}
win = getWindow(doc);
return {
top: box.top + win.pageYOffset - docElem.clientTop,
left: box.left + win.pageXOffset - docElem.clientLeft
};
};
function getHeight($element) {
var style = window.getComputedStyle($element, null);
return parseInt(style.getPropertyValue('height'), 10);
}
});