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.

Right… so big long post.

Well you’re transitioning in half a second, so it may be difficult for a browser to accomplish that smoothly. What happens if you try bumping your duration up?

Can you show us what happens when it doesnt work? Does it always not work on certain pages, or is it random? The description you give doesn’t really narrow down a cause, and it may be as simple as cloudfront blocking the image load.

1 Like

Actually, I’ve noticed two different problems:

  1. When I set a background image to the sticky menu in systeme.io’s page builder, the sticky menu’s toggle is not smooth enough. So, I think the issue comes from the image, because when I just set to the sticky menu a background color, the transition is smooth.

When I try bumping my duration up, the sticky menu still toggles abruptly.

=> I tried another solution by modifying the resetStyles function as follows:

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;
    // Reset the transitions
    stickyMenu.style.transition = `background-color ${transitionDuration} ease-in-out, background-image ${transitionDuration} ease-in-out`;
  }, 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;
    }

The sticky menu toggles in a smoother way, but the problem is that the background image is not fixed. Indeed, we can see the image scrolling down or scrolling up with every toggle.

  1. However, in some other pages, when I set a background color the sticky menu, a big image of the colored logo displays behind in addition to the logo’s image.

As you can see here:

But, when I remove this line below, the sticky menu doesn’t display this big image:

section.style.backgroundImage = url(${coloredLogoUrl});

If I remove this line of code above when I set a background image, then the sticky menu doesn’t transition from the background image to the background color.

Like I said in my first post, I need a general code that works for all systeme.io’s pages.

So when you emailed their support team (yaknow, because of the “24/7 email support” they promote on their pricing page), what did they say?

(I still cant derive a problem based on a picture, and since you seem unable to provide a link to anything other than the company’s website, I cant offer any advice.)

They don’t do support for custom codes.

I tried to add the link of the page, but I couldn’t because I have a new account.

Here is the link of my page that has the issue about the background image not smooth enough or scrolling up and down during the toggle:

https://lesfunnelsbuilders.systeme.io/codage

And here is the link of the page that shows a big image of the colored logo when this line of code section.style.backgroundImage = url(${coloredLogoUrl}); is not commented out:

https://lesfunnelsbuilders.systeme.io/a533eb61

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.