Repository navigation
Expand file tree
/
Copy pathscript.js
More file actions
122 lines (103 loc) · 3.95 KB
/
Copy pathscript.js
File metadata and controls
122 lines (103 loc) · 3.95 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
const toggleBtn = document.getElementById("theme-toggle")
const currentTheme =
localStorage.getItem("theme") || (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light")
// 1. Apply stored/system theme on load
document.documentElement.setAttribute("data-theme", currentTheme)
toggleBtn.textContent = currentTheme === "dark" ? "☀️" : "🌙"
// 2. Toggle on click
toggleBtn.addEventListener("click", () => {
const newTheme = document.documentElement.getAttribute("data-theme") === "dark" ? "light" : "dark"
document.documentElement.setAttribute("data-theme", newTheme)
localStorage.setItem("theme", newTheme)
toggleBtn.textContent = newTheme === "dark" ? "☀️" : "🌙"
})
// Hamburger menu functionality
const hamburgerToggle = document.getElementById("hamburger-toggle")
const navMenu = document.getElementById("nav-menu")
const navLinks = document.querySelectorAll(".nav-link")
// Toggle hamburger menu
hamburgerToggle.addEventListener("click", () => {
hamburgerToggle.classList.toggle("active")
navMenu.classList.toggle("active")
document.body.classList.toggle("menu-open")
})
// Close menu when clicking on nav links
navLinks.forEach((link) => {
link.addEventListener("click", () => {
hamburgerToggle.classList.remove("active")
navMenu.classList.remove("active")
document.body.classList.remove("menu-open")
})
})
// Close menu when clicking outside
document.addEventListener("click", (e) => {
if (!hamburgerToggle.contains(e.target) && !navMenu.contains(e.target)) {
hamburgerToggle.classList.remove("active")
navMenu.classList.remove("active")
document.body.classList.remove("menu-open")
}
})
// Close menu on escape key
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
hamburgerToggle.classList.remove("active")
navMenu.classList.remove("active")
document.body.classList.remove("menu-open")
}
})
// Timeline expand/collapse functionality for desktop and mobile
function setupTimelineExpanders() {
const timelineContents = document.querySelectorAll(".timeline-content")
timelineContents.forEach((tc) => {
const header = tc.querySelector(".timeline-header")
const expandArrow = tc.querySelector(".expand-arrow")
const closeBtn = tc.querySelector(".timeline-close-btn")
if (!header || !expandArrow || !closeBtn) return
// Remove existing event listeners by cloning
const newTc = tc.cloneNode(true)
tc.parentNode.replaceChild(newTc, tc)
const newHeader = newTc.querySelector(".timeline-header")
const newExpandArrow = newTc.querySelector(".expand-arrow")
const newCloseBtn = newTc.querySelector(".timeline-close-btn")
// Function to expand timeline
const expandTimeline = (e) => {
// Prevent expansion if clicking on links
if (e && e.target.closest("a")) {
return
}
newTc.classList.add("expanded")
}
// Function to collapse timeline
const collapseTimeline = (e) => {
e.stopPropagation()
newTc.classList.remove("expanded")
}
// Click on header or arrow to expand
newHeader.addEventListener("click", expandTimeline)
newExpandArrow.addEventListener("click", expandTimeline)
// Click close button to collapse
newCloseBtn.addEventListener("click", collapseTimeline)
// Prevent collapse when clicking inside the skills section
const skills = newTc.querySelector(".skills")
if (skills) {
skills.addEventListener("click", (e) => {
e.stopPropagation()
})
}
})
}
// Initialize on DOM load and window resize
window.addEventListener("DOMContentLoaded", setupTimelineExpanders)
window.addEventListener("resize", debounce(setupTimelineExpanders, 250))
// Debounce function to prevent excessive resize event handling
function debounce(func, wait) {
let timeout
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout)
func(...args)
}
clearTimeout(timeout)
timeout = setTimeout(later, wait)
}
}