Highlighting Menu Items Based on Scroll Position Using Code

I have a single-page website where different sections are scrolled into view as the user navigates down the page. I am trying to implement a feature that highlights the corresponding menu item in the navigation menu when a section comes into view.

I’ve followed a tutorial and written the necessary JavaScript code to accomplish this functionality but items are not being highlighted when their corresponding sections are scrolled into view.

Here’s a snippet of the code I’m using:

javascriptCopy code

// JavaScript code snippet
$w.onReady(function () {
    $w("#page1").onViewportEnter(handleScroll);
});

function handleScroll() {
    const scrollPosition = $w("#page1").scrollTo;
    highlightMenuItem(scrollPosition);
}

function highlightMenuItem(scrollPosition) {
    const anchorPositions = {
        MENU: $w("#section11").scrollTo(),
        ABOUT: $w("#section1").scrollTo(),
        OFFERING: $w("#section10").scrollTo(),
        VALUES: $w("#section9").scrollTo(),
        TEAM: $w("#section8").scrollTo(),
        CONTACT: $w("#section5").scrollTo()
    };

    const activeSection = Object.keys(anchorPositions).find(section => scrollPosition >= anchorPositions[section]);
    highlightMenu(activeSection);
}

function highlightMenu(menuItem) {
    let menuItems = $w('#horizontalMenu1').menuItems;

    menuItems.forEach(item => {
        item.textColor = "#ffffff"; // Reset text color for all menu items
    });

    const menuItemElement = menuItems.find(item => item.label === menuItem);

    if (menuItemElement) {
        menuItemElement.textColor = "#8B4513"; // Change text color of the active menu item to brown
    }
}

I’ve checked for common issues such as correct element IDs, event binding, and scroll positions, but I haven’t been able to pinpoint the exact cause of the problem.

Here is the link to my website: https://www.komela.org/

Any help would be greatly appreciated!

The issue in your code is that you’re trying to use the scrollTo function as a property to get the scroll position of an element. However, scrollTo is a method that scrolls to an element, it does not return the scroll position.

To fix this, you need to use the getBoundingRect method which returns an object that includes the y property. This y property represents the distance from the top of the viewport to the top of the bounding rectangle of the element.

Here’s how you can modify your handleScroll and highlightMenuItem functions:

function handleScroll() {
    $w("#page1").getBoundingRect()
        .then(rect => {
            highlightMenuItem(rect.y);
        });
}

function highlightMenuItem(scrollPosition) {
    const anchorPositions = {
        MENU: $w("#section11").getBoundingRect().then(rect => rect.y),
        ABOUT: $w("#section1").getBoundingRect().then(rect => rect.y),
        OFFERING: $w("#section10").getBoundingRect().then(rect => rect.y),
        VALUES: $w("#section9").getBoundingRect().then(rect => rect.y),
        TEAM: $w("#section8").getBoundingRect().then(rect => rect.y),
        CONTACT: $w("#section5").getBoundingRect().then(rect => rect.y)
    };

    Promise.all(Object.values(anchorPositions)).then(values => {
        const activeSection = Object.keys(anchorPositions).find((section, index) => scrollPosition >= values[index]);
        highlightMenu(activeSection);
    });
}