-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
120 lines (106 loc) · 3.51 KB
/
main.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
111
112
113
114
115
116
117
118
119
120
document.addEventListener("DOMContentLoaded", function () {
const observer = new IntersectionObserver(
(entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
const src = img.getAttribute("data-src");
img.setAttribute("src", src);
observer.unobserve(img);
}
});
},
{
rootMargin: "100px",
}
);
document.querySelectorAll("img[data-src]").forEach((img) => {
observer.observe(img);
});
});
window.addEventListener("DOMContentLoaded", () => {
const ctl = new CollapsibleTimeline("#timeline");
});
class CollapsibleTimeline {
constructor(el) {
this.el = document.querySelector(el);
this.init();
}
init() {
this.el?.addEventListener("click", this.itemAction.bind(this));
this.expandAllItems();
}
expandAllItems() {
const items = this.el.querySelectorAll(".timeline__arrow");
items.forEach((button) => {
const itemID = button.getAttribute("data-item");
const ctrld = this.el.querySelector(`#item${itemID}-ctrld`);
if (ctrld) {
button.setAttribute("aria-expanded", "true");
ctrld.removeAttribute("aria-hidden");
ctrld.classList.add("timeline__item-body--expanded");
const content = ctrld.querySelector(".timeline__item-body-content");
content.style.opacity = 1;
content.style.visibility = "visible";
}
});
}
animateItemAction(button, ctrld, contentHeight, shouldCollapse) {
const expandedClass = "timeline__item-body--expanded";
const animOptions = {
duration: 300,
easing: "cubic-bezier(0.65,0,0.35,1)",
};
if (shouldCollapse) {
button.ariaExpanded = "false";
ctrld.ariaHidden = "true";
ctrld.classList.remove(expandedClass);
animOptions.duration *= 2;
this.animation = ctrld.animate(
[
{ height: `${contentHeight}px` },
{ height: `${contentHeight}px` },
{ height: "0px" },
],
animOptions
);
} else {
button.ariaExpanded = "true";
ctrld.ariaHidden = "false";
ctrld.classList.add(expandedClass);
this.animation = ctrld.animate(
[{ height: "0px" }, { height: `${contentHeight}px` }],
animOptions
);
}
}
itemAction(e) {
const { target } = e;
const action = target?.getAttribute("data-action");
const item = target?.getAttribute("data-item");
if (action) {
const targetExpanded = action === "expand" ? "false" : "true";
const buttons = Array.from(
this.el?.querySelectorAll(`[aria-expanded="${targetExpanded}"]`)
);
const wasExpanded = action === "collapse";
for (let button of buttons) {
const buttonID = button.getAttribute("data-item");
const ctrld = this.el?.querySelector(`#item${buttonID}-ctrld`);
const contentHeight = ctrld.firstElementChild?.offsetHeight;
this.animateItemAction(button, ctrld, contentHeight, wasExpanded);
}
} else if (item) {
const button = this.el?.querySelector(`[data-item="${item}"]`);
const expanded = button?.getAttribute("aria-expanded");
if (!expanded) return;
const wasExpanded = expanded === "true";
const ctrld = this.el?.querySelector(`#item${item}-ctrld`);
const contentHeight = ctrld.firstElementChild?.offsetHeight;
this.animateItemAction(button, ctrld, contentHeight, wasExpanded);
}
}
}
function swapImage(element, newImageSrc) {
element.src = newImageSrc;
}