0

I have some javascript code that fires a click event when the user scrolls up or down past a specific element (.closemenu). I'm using this to automatically open and close a header menu when the user scrolls the page.

The problem I have is that this is firing too many times and causing lagging and glitching on scroll, I've found this post which shows the usage of throttling for scroll events but I can't get it to work with my current javascript which is:

<script>
jQuery(window).scroll(function() {
   var hT = jQuery('.closemenu').offset().top,
       hH = jQuery('.closemenu').outerHeight(),
       wH = jQuery(window).height(),
       wS = jQuery(this).scrollTop();
    console.log((hT-wH) , wS);
   if (wS > (hT+hH-wH) && (hT > wS) && (wS+wH > hT+hH)){
   jQuery('.menu-bar').trigger('click');
   }
});
</script>

I've tried a few variations but I can't work out what the issue is, does anyone know how can I throttle this event by 30ms or so?

2 Answers2

0

Try if the below code works for you. You can change the ES6 throttle function to ES5 if your browser doesn't support ES6.

var func = function(){
    var hT = jQuery('.closemenu').offset().top,
       hH = jQuery('.closemenu').outerHeight(),
       wH = jQuery(window).height(),
       wS = jQuery(this).scrollTop();
    console.log((hT-wH) , wS);
   if (wS > (hT+hH-wH) && (hT > wS) && (wS+wH > hT+hH)){
   jQuery('.menu-bar').trigger('click');
   }
}
jQuery(window).scroll(function() {
  throttle(func,30);
});


const throttle = (func, limit) => {
  let inThrottle
  return function() {
    const args = arguments
    const context = this
    if (!inThrottle) {
      func.apply(context, args)
      inThrottle = true
      setTimeout(() => inThrottle = false, limit)
    }
  }
}
Prashanth KR
  • 294
  • 2
  • 8
0

WORKING ANSWER:

<script>
jQuery(window).scroll(function() {
   var hT = jQuery('.closemenu').offset().top,
       hH = jQuery('.closemenu').outerHeight(),
       wH = jQuery(window).height(),
       wS = jQuery(this).scrollTop();
    console.log((hT-wH) , wS);
   if (wS > (hT+hH-wH) && (hT > wS) && (wS+wH > hT+hH)){
   jQuery('.menu-bar').trigger('click');
   }

function throttle(fn, threshhold, scope) {
  threshhold || (threshhold = 1250);
  var last,
      deferTimer;
  return function () {
    var context = scope || this;

    var now = +new Date,
        args = arguments;
    if (last && now < last + threshhold) {
      // hold on to it
      clearTimeout(deferTimer);
      deferTimer = setTimeout(function () {
        last = now;
        fn.apply(context, args);
      }, threshhold);
    } else {
      last = now;
      fn.apply(context, args);
    }
  };
}

});
</script>