I have a Table of Contents with id #TableOfContents
in which each href
points to a h2 or h3.
The problem I am having is that once the Heading, h2 or h3 is observed by intersection observer, Entry for that is highlighted by adding class side-active
for that link in #TableOfContents
, but as soon as the long content (such as p
paragraph) after the heading comes in viewport the highlight for that section is removed since the heading is not in viewport.
This is a problem since I want the section (h2, h3) to still be highlighted until next h2 or h3 doesn't cross half of viewport.
What can I do?
window.addEventListener('DOMContentLoaded', () => {
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
const id = entry.target.getAttribute('id');
if (entry.intersectionRatio > 0) {
document.querySelector(`#TableOfContents a[href="#${id}"]`).classList.add('side-active');
} else {
document.querySelector(`#TableOfContents a[href="#${id}"]`).classList.remove('side-active');
}
});
});
toc = document.querySelectorAll('#TableOfContents a');
// get content so that link refer to it
toc.forEach(function (link) {
var id = link.getAttribute("href");
var element = document.querySelector(id);
observer.observe(element);
});
});
Text is highlighted when heading in viewport
Text is not highlighted once heading is not in viewport
CodePudding user response:
So the thing was we needed to calculate containerBottom by:
adding current container's top next container's top
Or if it is last container then,
current container's top it's outerHeight()
Once that; if ith container is in scrollposition add class to it And remove class from all containers previous to ith container (line no 18-21) (reverse loop)
$(function () {
// Table of contents (`ul`) that contains `a` tag in `li` which we want to highlight
var sectionIds = $('#TableOfContents a');
$(document).on('scroll', function(){
sectionIds.each(function(i, e){
var container = $(this).attr('href');
var containerOffset = $(container).offset().top; // container's top
var nextContainer = $(sectionIds[i 1]).attr('href')
if (i != sectionIds.length-1) {
// if this container isn't last container
var containerHeight = $(nextContainer).offset().top;
} else {
// last container's height will be outerHeight
var containerHeight = $(container).outerHeight();
}
var containerBottom = containerOffset containerHeight;
var scrollPosition = $(document).scrollTop();
if(scrollPosition < containerBottom - 20 && scrollPosition >= containerOffset - 20){
for (var j = i; j >= 0; j--) {
$(sectionIds[j]).removeClass('active');
}
$(sectionIds[i]).addClass('active');
} else{
$(sectionIds[i]).removeClass('active');
}
});
});
});