-
Notifications
You must be signed in to change notification settings - Fork 40
Expand file tree
/
Copy path_resize-observer.html
More file actions
92 lines (84 loc) · 3.35 KB
/
_resize-observer.html
File metadata and controls
92 lines (84 loc) · 3.35 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
<script>
(function() {
function observeResizes() {
// Only run if ResizeObserver is supported.
if ('ResizeObserver' in self) {
// Create a single ResizeObserver instance to handle all
// container elements. The instance is created with a callback,
// which is invoked as soon as an element is observed as well
// as any time that element's size changes.
var ro = new ResizeObserver(function(entries) {
// Default breakpoints that should apply to all observed
// elements that don't define their own custom breakpoints.
var defaultBreakpoints = {SM: 384, MD: 576, LG: 768, XL: 960};
entries.forEach(function(entry) {
// If breakpoints are defined on the observed element,
// use them. Otherwise use the defaults.
var breakpoints = entry.target.dataset.breakpoints ?
JSON.parse(entry.target.dataset.breakpoints) :
defaultBreakpoints;
if (entry.contentRect.width === 0) {
entry.target.dataset.observing = false;
} else {
entry.target.dataset.observing = true;
}
// Update the matching breakpoints on the target element.
Object.keys(breakpoints).forEach(function(breakpoint) {
var minWidth = breakpoints[breakpoint];
if (entry.contentRect.width >= minWidth) {
entry.target.classList.add(breakpoint);
} else {
entry.target.classList.remove(breakpoint);
}
});
});
});
// Find all elements with the `data-observe-resizes` attribute
// and start observing them.
var elements = document.querySelectorAll('[data-observe-resizes]');
for (var element, i = 0; element = elements[i]; i++) {
ro.observe(element);
}
// Iterates through the subtree
var eachObserveableElement = function(nodes, fn) {
if (nodes) {
[].slice.call(nodes).forEach(function(node) {
if (node.nodeType === 1) {
var containers = [].slice.call(
node.querySelectorAll('[data-observe-resizes]'));
if (node.hasAttribute('data-observe-resizes')) {
containers.push(node);
}
for (var container, i = 0; container = containers[i]; i++) {
fn(container);
}
}
});
}
};
// Monitor the DOM for changes
var mo = new MutationObserver(function(entries) {
entries.forEach(function(entry) {
eachObserveableElement(entry.addedNodes, ro.observe.bind(ro));
});
});
mo.observe(document.body, {childList: true, subtree: true});
}
}
// A technique for loading polyfills only when needed. Details here:
// https://philipwalton.com/articles/loading-polyfills-only-when-needed/
if (window.ResizeObserver) {
// Browsers that support ResizeObserver run `observeResizes()` immediately.
observeResizes();
} else if (window.matchMedia('(min-width: 48em)').matches) {
// Other browsers at MD+ breakpoints load the polyfill first.
loadScript('{{ "resize-observer.js" | revision }}', observeResizes);
}
function loadScript(src, done) {
var js = document.createElement('script');
js.src = src;
js.onload = done;
document.head.appendChild(js);
}
})();
</script>