I'm trying to highlight the current section items in a sticky table of contents as you scroll down the page.
The structure is currently like:
<div>
<div>
<div>
<div>
<h2 id="twitter-chats-for-ecommerce">Header</h2>
<div>content...</div>
</div>
</div>
</div>
</div>
And the table of contents like:
<ul>
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 1</a></li>
<li><a href="#twitter-chats-for-ecommerce">Twitter Chats for Ecommerce</a></li>
</ul>
The anchor is being applied to the header automatically via a Gutenberg block in WordPress (in this case, the h2).
The existing JavaScript for this is the following:
(function($) {
/* Table of contents - highlight active section on scroll */
window.addEventListener('DOMContentLoaded', () => {
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
const id = entry.target.getAttribute('id');
if (entry.intersectionRatio > 0) {
document.querySelector(`nav li a[href="#${id}"]`).parentElement.classList.add('active');
} else {
document.querySelector(`nav li a[href="#${id}"]`).parentElement.classList.remove('active');
}
});
});
// Track all sections that have an `id` applied
document.querySelectorAll('h2[id]').forEach((section) => {
observer.observe(section);
});
});
})( jQuery );
But as you can see from the below example screenshot, the item in the table of contents is highlighting when the matching header (in this case h2) is visible on the page.
So in the case where there are multiple headers visible on the page, more than one item is highlighted in the TOC.
Ideally, I guess that it should be matching the div of the section but the id anchor is being applied to the header and I don't have control over this.
Is there a way I can modify the JS to somehow only detect the entire div section instead of just the header so that it will only ever have one item highlighted in the TOC - or is there even a better way than this?
An example of one that works perfectly that I'd like to achieve can be seen here (see the 'On This Page' section in right hand sidebar).
