Skip to content

Commit 5550938

Browse files
committed
add menu highlighting on scroll
1 parent 3655e87 commit 5550938

1 file changed

Lines changed: 83 additions & 90 deletions

File tree

js/app.js

Lines changed: 83 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -13,120 +13,113 @@ document.addEventListener("DOMContentLoaded", function () {
1313
}
1414

1515
// scroll to top of the page
16-
scrollToTopBtn.addEventListener("click", function (e) {
17-
e.preventDefault();
18-
window.scrollTo({
19-
top: 0,
20-
behavior: "smooth"
21-
})
22-
});
16+
if (scrollToTopBtn) {
17+
scrollToTopBtn.addEventListener("click", function (e) {
18+
e.preventDefault();
19+
window.scrollTo({
20+
top: 0,
21+
behavior: "smooth"
22+
})
23+
});
24+
}
2325

2426
// add/remove class 'scroll' on scroll by 5px
25-
let added = false;
26-
window.addEventListener('scroll', function () {
27-
if (window.scrollY > 5) {
28-
if (added) return;
29-
added = true;
30-
document.body.classList.add('scroll');
31-
} else {
32-
document.body.classList.remove('scroll');
33-
added = false;
27+
const scrollTarget = document.querySelector('.logo-container');
28+
const scrollObserver = new IntersectionObserver(
29+
([entry]) => {
30+
if (!entry.isIntersecting) {
31+
document.body.classList.add('scroll');
32+
} else {
33+
document.body.classList.remove('scroll');
34+
}
35+
},
36+
{
37+
root: null,
38+
threshold: 0,
39+
rootMargin: '0px 0px 0px 0px'
3440
}
35-
});
41+
);
42+
43+
if (scrollTarget) scrollObserver.observe(scrollTarget);
44+
45+
// heighlight current Menu on scroll
46+
const headings = Array.from(document.querySelectorAll("h2, h3"));
47+
const menuLinks = document.querySelectorAll("#menu li a");
48+
49+
const observerOptions = {
50+
rootMargin: "-200px 0px 0px 0px",
51+
};
52+
53+
const menuObserver = new IntersectionObserver((entries) => {
54+
entries.forEach((entry) => {
55+
if (entry.isIntersecting) {
56+
const currentApiPrefix = entry.target.id.split(".")[0];
57+
const parentMenuSelector = `#${currentApiPrefix}-menu`;
58+
const parentMenuEl = document.querySelector(parentMenuSelector);
59+
60+
// open submenu on scroll
61+
if (parentMenuEl) parentMenuEl.classList.add("active");
62+
63+
// Remove active class from last menu item
64+
const lastActiveMenu = document.querySelector(".active[id$='-menu']");
65+
if (lastActiveMenu && lastActiveMenu.id !== parentMenuEl.id) {
66+
lastActiveMenu.classList.remove("active");
67+
}
68+
69+
// Update active link
70+
menuLinks.forEach((link) => link.classList.remove("active"));
71+
const activeLink = document.querySelector(`a[href="#${entry.target.id}"]`);
72+
if (activeLink) activeLink.classList.add("active");
73+
}
74+
});
75+
}, observerOptions);
76+
77+
headings.forEach((heading) => menuObserver.observe(heading));
3678

3779
// i18n message box : this box appears hidden for all page.lang != 'en'
3880
const isI18nCookie = readCookie('i18nClose');
39-
if(i18nMsgBox && !isI18nCookie) {
81+
if (i18nMsgBox && !isI18nCookie) {
4082
const closeI18nBtn = document.getElementById("close-i18n-notice-box");
4183
// show notice box
4284
i18nMsgBox.hidden = false;
4385
// close notice box
4486
if (closeI18nBtn) {
45-
closeI18nBtn.addEventListener("click", ()=>{
87+
closeI18nBtn.addEventListener("click", () => {
4688
// hide notice
4789
i18nMsgBox.hidden = true;
4890
// set session cookie
4991
createCookie('i18nClose', 1);
50-
});
51-
// improve keyboard a11y for
92+
});
93+
94+
// keyboard a11y
5295
closeI18nBtn.addEventListener("keydown", (e) => {
5396
if (e.key === "Enter" || e.key === " ") {
5497
e.preventDefault();
5598
closeI18nBtn.click();
5699
}
57100
});
58-
}};
59-
});
60-
61-
62-
63-
$(function(){
64-
var doc = $(document);
65-
66-
// menu bar
67-
68-
var headings = $('h2, h3').map(function(i, el){
69-
return {
70-
top: $(el).offset().top - 200,
71-
id: el.id
72101
}
73-
});
74-
75-
function closest() {
76-
var h;
77-
var top = $(window).scrollTop();
78-
var i = headings.length;
79-
while (i--) {
80-
h = headings[i];
81-
if (top >= h.top) return h;
102+
};
103+
104+
function createCookie(name, value, days) {
105+
let expires = "";
106+
if (days) {
107+
const date = new Date();
108+
date.setTime(date.getTime() + (days * 864e5));
109+
expires = "; expires=" + date.toUTCString();
82110
}
111+
document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}${expires}; path=/; SameSite=Lax; Secure`;
83112
}
84113

85-
var currentApiPrefix;
86-
var parentMenuSelector;
87-
var lastApiPrefix;
88-
89-
$(document).scroll(function() {
90-
var h = closest();
91-
if (!h) return;
92-
93-
currentApiPrefix = h.id.split('.')[0];
94-
parentMenuSelector = '#'+ currentApiPrefix + '-menu';
95-
96-
$(parentMenuSelector).addClass('active');
97-
98-
if (lastApiPrefix && (lastApiPrefix != currentApiPrefix)) {
99-
$('#'+ lastApiPrefix + '-menu').removeClass('active');
114+
function readCookie(name) {
115+
const nameEQ = encodeURIComponent(name) + "=";
116+
const ca = document.cookie.split(';');
117+
for (var i = 0; i < ca.length; i++) {
118+
var c = ca[i];
119+
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
120+
if (c.indexOf(nameEQ) === 0) return decodeURIComponent(c.substring(nameEQ.length, c.length));
100121
}
101-
102-
$('#menu li a').removeClass('active');
103-
104-
var a = $('a[href="#' + h.id + '"]');
105-
a.addClass('active');
106-
107-
lastApiPrefix = currentApiPrefix.split('.')[0];
108-
})
109-
})
110-
111-
function createCookie(name, value, days) {
112-
let expires = "";
113-
if (days) {
114-
const date = new Date();
115-
date.setTime(date.getTime() + (days * 864e5));
116-
expires = "; expires=" + date.toUTCString();
122+
return null;
117123
}
118-
const secureFlag = location.protocol === "https:" ? "; Secure" : "";
119-
document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}${expires}; path=/; SameSite=Lax${secureFlag}`;
120-
}
121-
122-
123-
function readCookie(name) {
124-
var nameEQ = encodeURIComponent(name) + "=";
125-
var ca = document.cookie.split(';');
126-
for (var i = 0; i < ca.length; i++) {
127-
var c = ca[i];
128-
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
129-
if (c.indexOf(nameEQ) === 0) return decodeURIComponent(c.substring(nameEQ.length, c.length));
130-
}
131-
return null;
132-
}
124+
125+
});

0 commit comments

Comments
 (0)