/    Sign up×
Bounties /Pin to ProfileBookmark

Sticky Menu Toggling Smoothly on Scroll – JavaScript Code For systeme.io Pages

I need a JavaScript code to implement in my systeme.io pages that is able to make a sticky menu toggling smoothly on scroll.

The sticky menu should have an initial state and initial styles at the initial load of the page.

Then, when scrolling down the stcky menu toggles smoothly and the logo’s color, the background color, the menu’s links and the button’s background color change.

And Finally, when we scroll up and reach the top of the page, the sticky menu reset smoothly to its initial styles and initial state.

Here two example of what I would like to achieve:

https://www.make.com/en

https://impact2020.edf.org/

Here is my code:

<script>
  const logoImage = document.getElementById('image-c418c30e');
  const whiteLogoUrl = 'https://d1yei2z3i6k35z.cloudfront.net/4555433/64dc0781ef611_sticky-menu-white-logo.png';
  const coloredLogoUrl = 'https://d1yei2z3i6k35z.cloudfront.net/4555433/64dc0776841e4_sticky-menu-colored-logo.png';

  const coloredLogo = new Image();
  coloredLogo.src = coloredLogoUrl;

  const whiteLogo = new Image();
  whiteLogo.src = whiteLogoUrl;

  logoImage.src = whiteLogoUrl;

  document.addEventListener('DOMContentLoaded', function () {
    const stickyMenu = document.getElementById('section-4f6994fa');
    const menu = document.getElementById('menu-972c4b46');
    const button = document.getElementById('button-e246b912');
    const navigationLinks = menu.querySelectorAll('a');

    const initialStyles = {
      backgroundImage: stickyMenu.style.backgroundImage,
      backgroundColor: stickyMenu.style.backgroundColor,
      menuColor: menu.style.color,
      buttonColor: button.style.backgroundColor
    };

    const transitionDuration = '0.5s';
    
    menu.style.transition = `color ${transitionDuration} ease-in-out`;
    navigationLinks.forEach(link => {
      link.style.transition = `color ${transitionDuration} ease-in-out`;
    });
    button.style.transition = `background-color ${transitionDuration} ease-in-out`;
    logoImage.style.transition = `opacity ${transitionDuration} ease-in-out`;
    stickyMenu.style.transition = `background-color ${transitionDuration} ease-in-out`; // Faster transition

    let isAtTop = true;
    let isButtonBlack = false;
    let logoSwapped = false;
    let isTransitioning = false;

    function swapLogo(sourceUrl) {
      logoImage.style.opacity = '0';
      setTimeout(() => {
        logoImage.src = sourceUrl;
        logoImage.style.opacity = '1';
        logoSwapped = false;
      }, 300);
    }

    function smoothTransition(element, property, fromValue, toValue, duration) {
      const fps = 60;
      const interval = 1000 / fps;
      const steps = duration / interval;
      let stepCount = 0;
      
      const increment = (toValue - fromValue) / steps;

      const timer = setInterval(() => {
        if (stepCount >= steps) {
          clearInterval(timer);
          element.style[property] = toValue;
        } else {
          element.style[property] = `${fromValue + increment * stepCount}px`;
          stepCount++;
        }
      }, interval);
    }

function resetStyles(styles) {
  // Use a faster duration for the background color reset transition
  stickyMenu.style.transition = `background-color 0.3s ease-in-out`; // Add this line
  stickyMenu.style.backgroundColor = 'transparent'; // Set the background color to transparent
  setTimeout(() => {
    stickyMenu.style.backgroundImage = styles.backgroundImage;
    stickyMenu.style.backgroundColor = styles.backgroundColor;
    stickyMenu.style.transition = 'background-color 0.5s ease-in-out'; // Reset the transition
  }, 300); // Same timing as the background color transition

      // Reset other styles here
      menu.style.color = styles.menuColor;
      navigationLinks.forEach(link => {
        link.style.color = styles.menuColor;
      });
      button.style.backgroundColor = styles.buttonColor;
    }

function toggleBackgroundOnScroll(elementId) {
    const section = document.getElementById(elementId);
    if (!section) {
      console.error(`Element with ID "${elementId}" not found.`);
      return;
    }

    let prevScrollPos = window.scrollY;

    function handleScroll() {
      const currentScrollPos = window.scrollY;

      if (currentScrollPos === 0) {
        resetStyles(initialStyles);
        if (!logoSwapped) {
          swapLogo(whiteLogoUrl);
          logoSwapped = true;
        }
        isAtTop = true;
        if (isButtonBlack) {
          button.style.backgroundColor = initialStyles.buttonColor;
          isButtonBlack = false;
        }
        navigationLinks.forEach((link, index) => {
          link.style.color = initialStyles.menuColor;
        });
      } else if (currentScrollPos > 0 && currentScrollPos > prevScrollPos && isAtTop) {
        if (!isTransitioning) {
          isTransitioning = true;
          section.style.backgroundColor = 'white';
          menu.style.color = 'black';
          navigationLinks.forEach(link => {
            link.style.color = 'black';
          });
          button.style.backgroundColor = 'black';
          setTimeout(() => {
            section.style.backgroundImage = `url(${coloredLogoUrl})`;
            isTransitioning = false;
          }, 150); // Same timing as swapping the logo
        }
        if (!logoSwapped) {
          swapLogo(coloredLogoUrl);
          logoSwapped = true;
        }
        isAtTop = false;
      } else if (currentScrollPos < prevScrollPos && !isAtTop) {
        menu.style.color = initialStyles.menuColor;
        if (!isAtTop && currentScrollPos === 0) {
          if (logoSwapped) {
            swapLogo(whiteLogoUrl);
            logoSwapped = false;
          }
          button.style.backgroundColor = initialStyles.buttonColor;
          isButtonBlack = false;
          navigationLinks.forEach((link, index) => {
            link.style.color = initialStyles.menuColor;
          });
        }
      }

      prevScrollPos = currentScrollPos;
    }

    window.addEventListener('scroll', handleScroll);
  }

  toggleBackgroundOnScroll('section-4f6994fa');

  });
</script>

As you can see, the code targets several elements of the page by IDs and URLs. For example, the sticky menu has the ID ‘section-4f6994fa’. The logos swap between a colored logo and a white logo targeted by URLs.

This code kind of works, but there are few problems with it:

  1. The sticky menu does not toggles smoothly anough. It is too abrupt, especially at the end of the transition.
  2. This code doesn’t work with all my systeme.io’s pages. For example, I had to remove the line 121 in other pages for it to work:
section.style.backgroundImage = `url(${coloredLogoUrl})`;

When, I leave this line in the other page, the sticky menu’s background color changes to white, it displays a big image of the colored logo behind, besides the logo image. And when I remove this line of the code, the big image of the colored logo disappears and the code works.

However, when I remove this line of code in another systeme.io’s page, the sticky menu’s background color doesn’t transition to white at all.

Indeed, I need a general code, like a template, that would work in every systeme.io’s page. I would just have to replace the IDs and URLs.

to post a answer
JavaScript

2 Replies

Davinci•003 auto-replyYou can use the following JavaScript code to create a sticky menu that toggles smoothly on scroll for systeme.io pages:


// Get the navbar
var navbar = document.getElementById("navbar");

// Get the offset position of the navbar
var sticky = navbar.offsetTop;

// Add the sticky class to the navbar when you reach its scroll position. Remove "sticky" when you leave the scroll position
function myFunction() {
if (window.pageYOffset &gt;= sticky) {
navbar.classList.add("sticky")
} else {
navbar.classList.remove("sticky");
}
}

// When the user scrolls the page, execute myFunction
window.onscroll = function() {myFunction()};

Was this helpful?

Copy linkTweet thisAlerts:
@SempervivumAug 23.2023 — Your code is fairly complex and I wonder if it can be simplified. However I didn't take the trouble to derive the HTML and the behavior being required from the javascript.
This is a demo for the essentials of this subject:
https://jsfiddle.net/Sempervivum/d8moxpuh/3/
If this is not sufficient please post the URL of the page in question so that one can view the HTML and CSS either and the behavior.

BTW:
What about your previous question:
https://webdeveloper.com/bounties/i-use-a-funnel-builder-called-systeme-io-to-make-a-page-with-an-update-numbers-animation-this-function-i-wrote-is-able-to-update-numbers-when-you-scroll-down-until-you-reach-them-and-see-them-on-the/
Were you able to fix this?
×

Success!

Help @sofiane-abou-abderrahim spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.3,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...