Intersection Observer for highlighting nav li

Recently I am developing a simple one page website with 3 sections and I try to use Intersection Observer API to implement a function that allows me to scroll to a part of section and the correct li/link get highlighted on the nav, so for example if I scroll to about section, the about li/link on the nav gets highlighted and others don’t.

Is it doable using the Intersection Observer API cause my sections are all have different heights?

This is what I have now:


            <li class="li-one">One</li>
            <li class="li-two">Two</li>
            <li class="li-three">Three</li>

    <div class="main-container">
        <div class="hero"></div>
        <section class="section-one" data-li="li-one">
            <h1>Section One</h1>
        <section class="section-two" data-li="li-two">
            <h1>Section Two</h1>
        <section class="section-three" data-li="li-three">
            <h1>Section Three</h1>
    <script src="./script.js"></script>


    margin: 0;
    box-sizing: border-box;

    text-align: center;
    border: 2px solid blue;

    position: fixed;
    background-color: black;
    color: white;
    width: 100%;

header ul{
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;;

header ul li{
    padding: 2rem;
    list-style: none;
    font-size: 1.5rem;
    cursor: pointer;

    color: orange;

    height: 100vh;
    border: 4px solid red;

    display: flex;
    justify-content: center;
    align-items: center;
    border: 4px solid purple;

    display: flex;
    justify-content: center;
    align-items: center;
    border: 4px solid green;

    display: flex;
    justify-content: center;
    align-items: center;
    border: 4px solid orange;


const sections = [...document.querySelectorAll('section')];

const observerOptions = {
    root: null,
    rootMargin: '0px',
    threshold: 0.2,

const sectionObserver = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
        const getLiClass ='data-li');
        const getLiElement = document.querySelector(`.${getLiClass}`);
        if(window.innerHeight >= / 2 && entry.isIntersecting){
}, observerOptions);

sections.forEach((section) => {

I have tried different approaches using the intersection observer API and above approaches is my latest but as you can see it doesn’t highlights li/link on the nav one at a time, I also tried an approach that it highlights one at a time but problem with that approach is if I didn’t fully scroll out of a section and just scroll back the highlights li/link on the nav doesn’t respond(for example, scroll past section one to section two(but section one is still in view), the section two li/link gets highlighted and I scroll back to the section one the section one li/link on the nav is not highlighted but section two li/link still highlighted).

Is it doable using the intersection observer API with sections that have different heights?
(The reason I use intersection observer API is because I did some researches and it seems to have better performance compare to using window.addEventListener(‘scroll’,callback).