Skip to content

Commit a8d144b

Browse files
committed
Fix scrolling and ToC clicking
1 parent a2209e9 commit a8d144b

File tree

1 file changed

+65
-58
lines changed

1 file changed

+65
-58
lines changed

layouts/learning-path/single.html

Lines changed: 65 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -69,77 +69,84 @@ <h2 class="mb-4 mt-3 text-xl font-bold">{{ i18n "key.table-of-contents" }}</h2>
6969
</article>
7070

7171
<script>
72-
document.addEventListener('DOMContentLoaded', function () {
73-
const tocLinks = document.querySelectorAll('#TableOfContents a');
74-
const tocItems = Array.from(tocLinks);
75-
76-
// Get header elements linked by the ToC
77-
const headerElements = tocItems.map(link => {
72+
document.addEventListener('DOMContentLoaded', function () {
73+
const tocLinks = document.querySelectorAll('#TableOfContents a');
74+
const tocItems = Array.from(tocLinks);
75+
76+
// Get header elements linked by the ToC
77+
const headerElements = tocItems.map(link => {
7878
const targetId = link.getAttribute('href').slice(1);
7979
return document.getElementById(targetId);
80-
});
81-
82-
function onScroll() {
83-
const scrollPosition = window.scrollY + window.innerHeight / 5; // Adjust this value to target the middle of the viewport
84-
80+
});
81+
82+
let isClicking = false; // Flag to track click events
83+
84+
function updateActiveState() {
85+
if (isClicking) return; // Skip updating if we are in clicking state
86+
87+
const scrollPosition = window.scrollY + window.innerHeight / 2; // Center of the viewport
88+
8589
let activeIndex = -1;
8690
for (let i = 0; i < headerElements.length; i++) {
87-
const header = headerElements[i];
88-
if (header && header.getBoundingClientRect().top + window.scrollY <= scrollPosition) {
89-
activeIndex = i;
90-
} else {
91-
break;
92-
}
91+
const header = headerElements[i];
92+
if (header && header.getBoundingClientRect().top + window.scrollY <= scrollPosition) {
93+
activeIndex = i;
94+
} else {
95+
break;
96+
}
9397
}
94-
98+
9599
// Update active class on ToC links
96100
tocItems.forEach(link => link.classList.remove('active-element'));
97101
if (activeIndex !== -1) {
98-
tocItems[activeIndex].classList.add('active-element');
99-
100-
// Scroll the toc-container to make the active item visible
101-
const tocContainer = document.querySelector('.toc-container');
102+
tocItems[activeIndex].classList.add('active-element');
103+
104+
// Scroll the toc-container to make the active item visible
105+
const tocContainer = document.querySelector('.toc-container');
106+
if (tocContainer) {
102107
const activeItem = tocItems[activeIndex];
103-
104-
tocContainer.scrollTop = activeItem.offsetTop - tocContainer.offsetTop - tocContainer.clientHeight / 2 + activeItem.clientHeight / 2;
108+
const activeItemRect = activeItem.getBoundingClientRect();
109+
const tocContainerRect = tocContainer.getBoundingClientRect();
110+
const offset = activeItemRect.top - tocContainerRect.top - tocContainer.clientHeight / 2 + activeItem.clientHeight / 2;
111+
112+
tocContainer.scrollTop = offset;
113+
}
105114
}
106-
}
107-
108-
// Smooth scrolling and setting active state on click
109-
tocItems.forEach((item) => {
115+
}
116+
117+
// Smooth scrolling and setting active state on click
118+
tocItems.forEach((item) => {
110119
item.addEventListener('click', function (event) {
111-
const targetId = item.getAttribute('href').slice(1);
112-
const targetElement = document.getElementById(targetId);
113-
114-
if (targetElement) {
115-
event.preventDefault();
116-
targetElement.scrollIntoView({
117-
// behavior: 'smooth',
118-
block: 'start'
119-
});
120-
121-
tocItems.forEach(link => link.classList.remove('active-element'));
122-
item.classList.add('active-element');
123-
}
124-
});
125-
});
126-
127-
// Throttle the scroll event
128-
let isScrolling = false;
129-
window.addEventListener('scroll', function () {
130-
if (!isScrolling) {
131-
window.requestAnimationFrame(function () {
132-
onScroll();
133-
isScrolling = false;
120+
const targetId = item.getAttribute('href').slice(1);
121+
const targetElement = document.getElementById(targetId);
122+
123+
if (targetElement) {
124+
event.preventDefault();
125+
isClicking = true; // Set flag to true when clicking
126+
targetElement.scrollIntoView({
127+
behavior: 'auto', // No smooth scrolling
128+
block: 'start'
134129
});
135-
isScrolling = true;
136-
}
130+
131+
// Highlight the clicked ToC item
132+
tocItems.forEach(link => link.classList.remove('active-element'));
133+
item.classList.add('active-element');
134+
135+
// Reset flag after scroll completes
136+
setTimeout(() => isClicking = false, 100); // Short timeout to reset flag
137+
}
138+
});
139+
});
140+
141+
// Handle scroll events
142+
window.addEventListener('scroll', function () {
143+
updateActiveState();
144+
});
145+
146+
// Initial check to set the active element on page load
147+
updateActiveState();
137148
});
138-
139-
// Initial check to set the active element on page load
140-
onScroll();
141-
});
142-
</script>
149+
</script>
143150

144151
<section id="mark-complete" class="hidden w-full flex-col items-start justify-between">
145152
<div class="mx-auto w-full rounded-xl border border-green-400 bg-white shadow-lg">

0 commit comments

Comments
 (0)