Search code examples
javascriptcssaddeventlisteneronscrolllistener

How to fix window scroll event listener for firefox?


  • I have made a function which adds/removes classes to navigation depending upon window scroll position. https://kmanadkat.github.io/navonscroll/

  • It is working in Chrome Desktop and Mobile, but it is failing for Firefox. Surprisingly, examples i mentioned on above website are working on firefox but not the home page.

  • I have tried a lot to findout the bug, there is no console log from window.onscroll function . I want to keep this plugin in pure Vanilla Javascript , still i tried with arrow notations to see if they fix, but they didnot work.

  • Everything is working in chrome, just firefox is not able to get along with window.onscroll,
  • i even tried window.addEventListener("scroll", function() {});, but it isn't working too, on tabs other than my website, i am able to do onscrollevents with developer tools.

  • Here is the complete Code of plugin :


function hide_on_scroll(obj) {
  // Throw Error if input type is not object or navid is not passed
  if(typeof(obj)!=="object" || obj.nav_id===undefined){
    throw new TypeError("Argument must be an Object, also confirm NavId");
  }

  // Get Function Paramenters
  var nav_id                  = obj.nav_id;
  var nav_offset              = !!obj.nav_offset ? obj.nav_offset : 200;
  var nav_position            = !!obj.nav_position ? obj.nav_position : 'top';
  var hide_onscroll_mobile    = !!obj.hide_onscroll_mobile ? true : false;
  var mobile_width            = !!obj.mobile_width ? obj.mobile_width : 576;
  nav_position = nav_position.toLowerCase();

  // Prepare Navbar
  var navbar = document.getElementById(nav_id);
  if(navbar==undefined){throw new TypeError("Recheck Passed Navigation Id"); }

  var nav_height = navbar.offsetHeight;
  var navClasses = document.createElement('style');
  navClasses.type = 'text/css';
  navClasses.innerHTML = 
  '.nav-scroll-up{-webkit-transform: translateY(-'+78+'px);-ms-transform: translateY(-'+78+'px);transform: translateY(-'+78+'px);}' +
  '.nav-scroll-down{-webkit-transform: translateY('+78+'px);-ms-transform: translateY('+78+'px);transform: translateY('+78+'px);}' +
  '.nav-scroll-fixed-'+ nav_position +'{position: fixed;'+ nav_position +': 0;right: 0;left: 0;z-index: 1000;}' +
  '.nav-scroll-transition{will-change: transform; -webkit-transition: -webkit-transform 0.5s cubic-bezier(0.5, 0, 0.25, 1);transition: -webkit-transform 0.5s cubic-bezier(0.5, 0, 0.25, 1);-o-transition: transform 0.5s cubic-bezier(0.5, 0, 0.25, 1);transition: transform 0.5s cubic-bezier(0.5, 0, 0.25, 1);transition: transform 0.5s cubic-bezier(0.5, 0, 0.25, 1), -webkit-transform 0.5s cubic-bezier(0.5, 0, 0.25, 1);}';
  document.getElementsByTagName('head')[0].appendChild(navClasses);
  navbar.classList.add('nav-scroll-transition');
  navbar.classList.add('nav-scroll-fixed-' + nav_position);


  // Set Global Variables
  var c=0;
  var currentScrollTop = 0;
  var scrollingClass = (nav_position==='top') ? 'nav-scroll-up' : 'nav-scroll-down';
  var width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
  // Get Current Viewport Width
  window.onresize = function(){ width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);}
  // Call Window OnScroll
  window.onscroll = function() {
    // disable Hide on scroll for mobile
    if(hide_onscroll_mobile==false && width<=mobile_width){
      if(navbar.classList.contains(scrollingClass)){ navbar.classList.remove(scrollingClass); }
    }

    // Hide On Scroll for all screen if (width > mobile_width or mobile_width==true)
    else{
      var a = window.scrollY;
      currentScrollTop = a;
      if (c < currentScrollTop && a > (2*nav_offset)) { 
        navbar.classList.add(scrollingClass); 
      }
      else if (c > currentScrollTop && !(a <= nav_offset)) { 
        navbar.classList.remove(scrollingClass); 
      }
      c = currentScrollTop;
    }
  };
}
  • How i want to call it from html, the above code is from file navonscroll.js
  <script src="navonscroll.js"></script>
  <script>
    hide_on_scroll({
      nav_id: 'myscrolling_nav',
      hide_onscroll_mobile : true,
      nav_offset : 10
    });
  </script>

I hope someone could help me fix it directly on git and contribute for this opensource kind of plugin or some fix in stackoverflow would also helps.


Solution

  • This is apparently a CSS issue, so this is going to be an incomplete answer (it's not really my area), but it appears the window.scroll event is not fired at all on Firefox, due to a combination of:

    • scroll-behavior: smooth; on the html element,
    • height: 100vh; + overflow: auto; on the body element.

    If you remove any of these rules from your main.css file, then the JS event will fire again.

    Someone with more CSS expertise might understand what's going on and what is the most appropriate way to adjust these rules, even though that kinda seems like a Firefox bug to me.