-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaddons.js
80 lines (67 loc) · 1.95 KB
/
addons.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
class Accordion {
constructor(el) {
this.el = el;
this.summary = el.querySelector('summary');
this.content = el.querySelector('.content');
this.animation = null;
this.isClosing = false;
this.isExpanding = false;
this.summary.addEventListener('click', (e) => this.onClick(e));
}
onClick(e) {
e.preventDefault();
this.el.style.overflow = 'hidden';
if (this.isClosing || !this.el.open) {
this.open();
} else if (this.isExpanding || this.el.open) {
this.shrink();
}
}
shrink() {
this.isClosing = true;
const startHeight = `${this.el.offsetHeight}px`;
const endHeight = `${this.summary.offsetHeight}px`;
if (this.animation) {
this.animation.cancel();
}
this.animation = this.el.animate({
height: [startHeight, endHeight]
}, {
duration: 400,
easing: 'ease-out'
});
this.animation.onfinish = () => this.onAnimationFinish(false);
this.animation.oncancel = () => this.isClosing = false;
}
open() {
this.el.style.height = `${this.el.offsetHeight}px`;
this.el.open = true;
window.requestAnimationFrame(() => this.expand());
}
expand() {
this.isExpanding = true;
const startHeight = `${this.el.offsetHeight}px`;
const endHeight = `${this.summary.offsetHeight + this.content.offsetHeight}px`;
if (this.animation) {
this.animation.cancel();
}
this.animation = this.el.animate({
height: [startHeight, endHeight]
}, {
duration: 400,
easing: 'ease-out'
});
this.animation.onfinish = () => this.onAnimationFinish(true);
this.animation.oncancel = () => this.isExpanding = false;
}
onAnimationFinish(open) {
this.el.open = open;
this.animation = null;
this.isClosing = false;
this.isExpanding = false;
this.el.style.height = this.el.style.overflow = '';
}
}
document.querySelectorAll('details').forEach((el) => {
new Accordion(el);
});