1

I want to call a function depending upon the direction of scroll i.e if we scroll down it call goDown() and if we scroll up then call goUp().
Here is my code :

  $('.container').on('DOMMouseScroll mousewheel', function (e) {
    if(e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) { 
      console.log('down');
      goDown();
    } else {
      console.log('up');
      goUp();
    }

    return false;
  });    

But if we scroll it is firing goDown() or goUp() multiple times which is not as I wanted, I just want to fire it once per scroll.

  • Take a look [here](http://stackoverflow.com/questions/34822077/scroll-function-firing-multiple-times-instead-of-once) – Dwhitz May 14 '17 at 13:00

3 Answers3

0

Use lodash's throttle.
In the example below, 1000 (1s) is the time which has to pass without any call to onScroll() before it can fire it again.

  $('.container').on(
    'DOMMouseScroll mousewheel', 
    _.throttle(
       onScroll, 
       1000, 
       {trailing: false}
    )
  );   
  
  // your original function, named:
  function onScroll (e) {
    if(e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) { 
      console.log('scrolled down');
      // goDown();
    } else {
      console.log('scrolled up');
      // goUp();
    }

    return false;
  }
.container {
  height: 200vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container"></div>

If you want to fire onScroll() at the end of your wait period, not at start, use

{leading:false,trailing:true}

...as options (last param).

Also note there's a jQuery plugin for throttle and debounce but I never used it. What I know is that it has a slightly different syntax/approach to each (than _). Feel free to look into it if you don't want to load Lodash in your project.

tao
  • 82,996
  • 16
  • 114
  • 150
0

you can make it with an timeout.

this is my oneliner

t=onscroll=e=>clearTimeout(t,t=setTimeout('console.log("finished")',500))

or with a few more lines:

var scrollWait,
  scrollFinished = () => console.log('finished');
  window.onscroll = () => {
    clearTimeout(scrollWait);
    scrollWait = setTimeout(scrollFinished,500);
  }

This codes wait for 500ms an then fire finished.

You can translate this to your own situation.

Frank Wisniewski
  • 1,182
  • 8
  • 7
0

I solved the problem in this way (please note that code should be optimized):

$(document).ready(function(){ 

  var valid = true;
  var power = 0; // <-- initial power

  setInterval(function(){
    if (power>0){
      power=power/2; // <-- decrease power every 250ms
      if (power<1) power=0;
      console.log(power); // <-- you may remove this
    }
  },250);

  $('.container').on('DOMMouseScroll mousewheel', function (e) {
    e.preventDefault();

    var c_power = Math.abs(e.originalEvent.wheelDeltaY)+Math.abs(e.originalEvent.wheelDeltaX); // <-- get current power

    /* event is considered valid only if current power > power */
    if (c_power>=power){
      power=c_power;
      valid=true;
    }

    if(valid && (e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0)) { 
      console.log('down');
      goDown();
    } else {
      console.log('up');
      goUp();
    }

    return false;
  });

});
Franz
  • 645
  • 1
  • 9
  • 21