375

I'm looking for something to this effect:

$(window).scroll(function(event){
   if (/* magic code*/ ){
       // upscroll code
   } else {
      // downscroll code
   }
});

Any ideas?

ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
Zach
  • 18,594
  • 18
  • 59
  • 68
  • 1
    Easiest to use the `wheel` event these days : http://stackoverflow.com/a/33334461/3168107. – Shikkediel Oct 29 '15 at 11:41
  • For those having problems with elastic scrolling, please use this answer https://stackoverflow.com/questions/7154967/jquery-detect-scrolldown – Timothy Dalton Nov 20 '13 at 07:48

25 Answers25

756

Check current scrollTop vs previous scrollTop

var lastScrollTop = 0;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
       // downscroll code
   } else {
      // upscroll code
   }
   lastScrollTop = st;
});
Josiah Ruddell
  • 29,697
  • 8
  • 65
  • 67
  • 17
    Any way to set a sensibility for this ? – cocoa coder Nov 30 '12 at 00:24
  • 10
    I made an example at [this](http://codepen.io/josiahruddell/pen/piFfq) codepen. Maybe I'll update update this answer with a jQuery plugin because of the popularity. – Josiah Ruddell Nov 30 '12 at 20:15
  • 3
    Have you tried this if you come back to a previous page having this code ? If you scroll down your page, let say 500PX. Go to another page and then back to initial page. Some browsers keep the scroll position and will bring you back down the page. Will you have a starting `lastScrollTop` at 0 or will it be properly initialised ?? – TCHdvlp Aug 23 '13 at 12:57
  • 7
    @TCHdvlp - well worst case scenario the **first** scroll event would update the variable and the **second** event would be accurate (.. it would only matter on an upscroll after back navigation). This could be fixed by setting `var lastScrollTop = $(window).scrollTop()` after the browser updates the scroll position on page load. – Josiah Ruddell Aug 26 '13 at 17:07
  • On Macs, anyone else notice if you scroll all the way to the bottom that it bounces and will fire off the event? – Strawberry Apr 01 '14 at 09:58
  • You might as well take note of `scrollLeft()` as well. Plenty of scrolling mice and trackpads scroll left and right. – mattalxndr May 11 '14 at 15:50
  • 2
    An update on this: Be careful that some browsers, specially IE 11 on Windows 8, can fire a scroll event subpixel-based (smooth scrolling). But because it reports scrollTop as an integer, your previous scroll value could be the same as the current one. – Renato Nov 26 '14 at 00:10
  • @Renato Thanks. I checked same problem at IE 8 on Win 7 and IE 11 on Win 8. In this case, [this answer](http://stackoverflow.com/questions/7154967/jquery-detect-scrolldown/#answer-7309786) helped me to solve problem. – Chemical Programmer Apr 18 '15 at 13:44
  • 1
    Just a small suggestion on that: Instead of if (st > lastScrollTop) you could also use if (st >= lastScrollTop). Otherwise, I noticed that when I scrolled up, for a moment it was executing the scroll down code before firing up the scroll up code. – giorgos Aug 20 '15 at 10:47
  • How about detect scroll direction hover non-scrollable content ? – Sebastien Sep 24 '15 at 13:15
  • @cocoacoder did you find anything about the sensibility thing? I found this http://stackoverflow.com/questions/14426548/how-to-change-default-scrollspeed-scrollamount-scrollinertia-of-a-webpage#answer-14430585 – R01010010 Oct 30 '16 at 11:51
  • When putting function to fire inside "up" or "down" scroll, it fires a loooot of times.. meaning if you scroll "heavily" on mac (fast pull up with 3 fingers on touchpad), the function will be executed constantly until scroll actually stops. How come no one mentioned that as its quite important ? Is there a way to detect just scroll start + direction and prevent actual scroll with mouse wheel ? – Blue May 21 '17 at 21:57
  • @Blue I made and example [here](http://codepen.io/josiahruddell/pen/piFfq), (see the comments above) – Josiah Ruddell May 24 '17 at 05:45
  • @JosiahRuddell Thank you, but this stil show multiple "down" when scrolled "once". I say "once" as I make usual long scroll down, It should fire only once. For that I managed to make it work with the locker on first scroll and releases locker afted 250ms. In chrome works like a charm, firefox fires two scrolls, on safari it doesnt really work..well, sensitivity is high so if scrolling gently wanted effect is achieved. This is how the scroll should work [here](https://alvarotrigo.com/fullPage/).Plugin for WP is pretty shitty and awful to build page so I had to made it myself.. – Blue May 24 '17 at 08:37
  • Im talking about mouse wheel scroll just to clarify :) – Blue May 24 '17 at 08:37
  • this what i thought up on my own, but this approach creates so many potential issues!! – oldboy Mar 15 '19 at 22:29
  • @cocoacoder try this: var lastScrTop = 0; var lastScrolltrig = 0; $(window).scroll(function(event){ var st = $(this).scrollTop(); if (st > lastScrTop){ // downscroll code lastScrolltrig = 0; } else { // upscroll code if ( lastScrolltrig === 0 ) { lastScrolltrig = $(this).scrollTop(); } if ( lastScrolltrig - $(this).scrollTop() >= 300 ) { // 300px buffer, run code here } } lastScrTop = st; }); – kakashigr Oct 06 '20 at 17:02
181

You can do it without having to keep track of the previous scroll top, as all the other examples require:

$(window).bind('mousewheel', function(event) {
    if (event.originalEvent.wheelDelta >= 0) {
        console.log('Scroll up');
    }
    else {
        console.log('Scroll down');
    }
});

I am not an expert on this so feel free to research it further, but it appears that when you use $(element).scroll, the event being listened for is a 'scroll' event.

But if you specifically listen for a mousewheel event by using bind, the originalEvent attribute of the event parameter to your callback contains different information. Part of that information is wheelDelta. If it's positive, you moved the mousewheel up. If it's negative, you moved the mousewheel down.

My guess is that mousewheel events will fire when the mouse wheel turns, even if the page does not scroll; a case in which 'scroll' events probably are not fired. If you want, you can call event.preventDefault() at the bottom of your callback to prevent the page from scrolling, and so that you can use the mousewheel event for something other than a page scroll, like some type of zoom functionality.

CharlesB
  • 86,532
  • 28
  • 194
  • 218
cilphex
  • 6,006
  • 6
  • 34
  • 44
  • 13
    Nice but sadly the one and only Firefox is not supporting it https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/mousewheel (tested in FF v15). :C – nuala Sep 17 '12 at 14:07
  • 8
    This was useful for me: I needed to detect scrolling, even though the page itself didn't actually scroll, so `scrollTop` didn't update. In fact, `$(window).scroll()` didn't fire at all. – Martti Laine Dec 14 '12 at 14:16
  • 14
    It's nice that you don't need the old state. However this technique will not work on mobiles or tablets, since they don't have a mousewheel! – joeytwiddle Aug 01 '13 at 04:43
  • 1
    I found this to be a nice and easy solution in firefox and chrome. Thank you good sir – corvid Jan 23 '14 at 20:45
  • 13
    This approach won't work if I scroll with the keyboard. It's definitely an interesting approach for things like zoom, but I don't think it addresses the scroll direction question. – chmac Feb 04 '14 at 09:33
  • 2
    while I used this technique until now, it won't work if the page is scrolled without the mousewheel. e.g. via mouse on the scrollbar. Also: Firefox only supports `DOMmousescroll` – ProblemsOfSumit Jul 25 '14 at 07:46
  • 6
    $("html, body").bind({'mousewheel DOMMouseScroll onmousewheel touchmove scroll': function(e) { //... }); works for me in detecting all browser scroll data – GoreDefex Nov 04 '14 at 19:15
  • Can the console.log wait until the scroll happens twice? – Jim Nov 11 '14 at 16:18
  • that's just plain bad. Touch scroll? scroll by clicking on the scrollbar and moving it down? just nope – Toskan May 11 '15 at 09:40
  • 2
    +1 because this led me in the right direction to solve my problem: `event.wheelDeltaX` and `event.wheelDeltaY` – scott Aug 03 '16 at 23:47
  • 1
    Note that mousewheel and scroll are not the same events. This will only work if user scrolls with mousewheel or touchpad. – Maciej Krawczyk Sep 03 '16 at 07:47
  • Dude you saved my day with your mousewheel event. For some reason I couldn't get scroll event fired up at all, but your solution worked like a charm!!! Thanx! – JSEvgeny Sep 07 '17 at 13:41
  • Good idea, but Firefox (75) doesn't like it at all. Even when doing it like @GoreDefex described. – Jonathan Arbely Mar 25 '20 at 15:22
34

Existing Solution

There could be 3 solution from this posting and other answer.

Solution 1

    var lastScrollTop = 0;
    $(window).on('scroll', function() {
        st = $(this).scrollTop();
        if(st < lastScrollTop) {
            console.log('up 1');
        }
        else {
            console.log('down 1');
        }
        lastScrollTop = st;
    });

Solution 2

    $('body').on('DOMMouseScroll', function(e){
        if(e.originalEvent.detail < 0) {
            console.log('up 2');
        }
        else {
            console.log('down 2');
        }
    });

Solution 3

    $('body').on('mousewheel', function(e){
        if(e.originalEvent.wheelDelta > 0) {
            console.log('up 3');
        }
        else {
            console.log('down 3');
        }
    });

Multi Browser Test

I couldn't tested it on Safari

chrome 42 (Win 7)

  • Solution 1
    • Up : 1 event per 1 scroll
    • Down : 1 event per 1 scroll
  • Solution 2
    • Up : Not working
    • Down : Not working
  • Solution 3
    • Up : 1 event per 1 scroll
    • Down : 1 event per 1 scroll

Firefox 37 (Win 7)

  • Solution 1
    • Up : 20 events per 1 scroll
    • Down : 20 events per 1 scroll
  • Solution 2
    • Up : Not working
    • Down : 1 event per 1 scroll
  • Solution 3
    • Up : Not working
    • Down : Not working

IE 11 (Win 8)

  • Solution 1
    • Up : 10 events per 1 scroll (side effect : down scroll occured at last)
    • Down : 10 events per 1 scroll
  • Solution 2
    • Up : Not working
    • Down : Not working
  • Solution 3
    • Up : Not working
    • Down : 1 event per 1 scroll

IE 10 (Win 7)

  • Solution 1
    • Up : 1 event per 1 scroll
    • Down : 1 event per 1 scroll
  • Solution 2
    • Up : Not working
    • Down : Not working
  • Solution 3
    • Up : 1 event per 1 scroll
    • Down : 1 event per 1 scroll

IE 9 (Win 7)

  • Solution 1
    • Up : 1 event per 1 scroll
    • Down : 1 event per 1 scroll
  • Solution 2
    • Up : Not working
    • Down : Not working
  • Solution 3
    • Up : 1 event per 1 scroll
    • Down : 1 event per 1 scroll

IE 8 (Win 7)

  • Solution 1
    • Up : 2 events per 1 scroll (side effect : down scroll occured at last)
    • Down : 2~4 events per 1 scroll
  • Solution 2
    • Up : Not working
    • Down : Not working
  • Solution 3
    • Up : 1 event per 1 scroll
    • Down : 1 event per 1 scroll

Combined Solution

I checked that side effect from IE 11 and IE 8 is come from if else statement. So, I replaced it with if else if statement as following.

From the multi browser test, I decided to use Solution 3 for common browsers and Solution 1 for firefox and IE 11.

I referred this answer to detect IE 11.

    // Detect IE version
    var iev=0;
    var ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent));
    var trident = !!navigator.userAgent.match(/Trident\/7.0/);
    var rv=navigator.userAgent.indexOf("rv:11.0");

    if (ieold) iev=new Number(RegExp.$1);
    if (navigator.appVersion.indexOf("MSIE 10") != -1) iev=10;
    if (trident&&rv!=-1) iev=11;

    // Firefox or IE 11
    if(typeof InstallTrigger !== 'undefined' || iev == 11) {
        var lastScrollTop = 0;
        $(window).on('scroll', function() {
            st = $(this).scrollTop();
            if(st < lastScrollTop) {
                console.log('Up');
            }
            else if(st > lastScrollTop) {
                console.log('Down');
            }
            lastScrollTop = st;
        });
    }
    // Other browsers
    else {
        $('body').on('mousewheel', function(e){
            if(e.originalEvent.wheelDelta > 0) {
                console.log('Up');
            }
            else if(e.originalEvent.wheelDelta < 0) {
                console.log('Down');
            }
        });
    }
Kyeno
  • 592
  • 2
  • 7
  • 16
Chemical Programmer
  • 4,352
  • 4
  • 37
  • 51
  • If someone could add result of `Safari browser`, it would be helpful to supplement solution. – Chemical Programmer Apr 18 '15 at 18:07
  • Oops! I found that Mobile Chrome and Android default browser are only covered by Solution 1. So it would be better to use both Solution 1 and 3 together to cover various browsers. – Chemical Programmer Apr 18 '15 at 18:25
  • Will not work if the design is a fixed layout design. If you want to detect the scroll direction on a static no-scroll website, Firefox and IE11 will not work – Shannon Hochkins Jan 05 '16 at 22:04
  • I find that when I use this it uses the "Other Browsers" in chrome, this is not really much use when you wish to detect scrolling by both mouse wheel and scroll bar. .scroll will detect both types of scrolling in chrome. – Someone Sep 06 '19 at 09:50
33

Store the previous scroll location, then see if the new one is greater than or less than that.

Here's a way to avoid any global variables (fiddle available here):

(function () {
    var previousScroll = 0;

    $(window).scroll(function(){
       var currentScroll = $(this).scrollTop();
       if (currentScroll > previousScroll){
           alert('down');
       } else {
          alert('up');
       }
       previousScroll = currentScroll;
    });
}()); //run this anonymous function immediately
Skilldrick
  • 69,215
  • 34
  • 177
  • 229
12

I understand there has already been an accepted answer, but wanted to post what I am using in case it can help anyone. I get the direction like cliphex with the mousewheel event but with support for Firefox. It's useful doing it this way in case you are doing something like locking scroll and can't get the current scroll top.

See a live version here.

$(window).on('mousewheel DOMMouseScroll', function (e) {

    var direction = (function () {

        var delta = (e.type === 'DOMMouseScroll' ?
                     e.originalEvent.detail * -40 :
                     e.originalEvent.wheelDelta);

        return delta > 0 ? 0 : 1;
    }());

    if(direction === 1) {
       // scroll down
    }
    if(direction === 0) {
       // scroll up
    }
});
souporserious
  • 2,079
  • 2
  • 27
  • 47
  • @EtienneMartin the above code relies on jQuery if that's what was causing your error. Please see the attached fiddle to see it working. – souporserious Jan 28 '15 at 20:16
8

Scroll Event

The scroll event behaves oddly in FF (it is fired a lot of times because of the smoothness scrolling) but it works.

Note: The scroll event actually is fired when dragging the scroll bar, using cursor keys or mousewheel.

//creates an element to print the scroll position
$("<p id='test'>").appendTo("body").css({
    padding: "5px 7px",
    background: "#e9e9e9",
    position: "fixed",
    bottom: "15px",
    left: "35px"
});

//binds the "scroll" event
$(window).scroll(function (e) {
    var target = e.currentTarget,
        self = $(target),
        scrollTop = window.pageYOffset || target.scrollTop,
        lastScrollTop = self.data("lastScrollTop") || 0,
        scrollHeight = target.scrollHeight || document.body.scrollHeight,
        scrollText = "";

    if (scrollTop > lastScrollTop) {
        scrollText = "<b>scroll down</b>";
    } else {
        scrollText = "<b>scroll up</b>";
    }

    $("#test").html(scrollText +
      "<br>innerHeight: " + self.innerHeight() +
      "<br>scrollHeight: " + scrollHeight +
      "<br>scrollTop: " + scrollTop +
      "<br>lastScrollTop: " + lastScrollTop);

    if (scrollHeight - scrollTop === self.innerHeight()) {
      console.log("► End of scroll");
    }

    //saves the current scrollTop
    self.data("lastScrollTop", scrollTop);
});

Wheel Event

You also may take a look at MDN, it exposes a great information about the Wheel Event.

Note: The wheel event is fired only when using the mousewheel; cursor keys and dragging the scroll bar does not fire the event.

I read the document and the example: Listening to this event across browser
and after some tests with FF, IE, chrome, safari, I ended up with this snippet:

//creates an element to print the scroll position
$("<p id='test'>").appendTo("body").css({
    padding: "5px 7px",
    background: "#e9e9e9",
    position: "fixed",
    bottom: "15px",
    left: "15px"
});

//attach the "wheel" event if it is supported, otherwise "mousewheel" event is used
$("html").on(("onwheel" in document.createElement("div") ? "wheel" : "mousewheel"), function (e) {
    var evt = e.originalEvent || e;

    //this is what really matters
    var deltaY = evt.deltaY || (-1 / 40 * evt.wheelDelta), //wheel || mousewheel
        scrollTop = $(this).scrollTop() || $("body").scrollTop(), //fix safari
        scrollText = "";

    if (deltaY > 0) {
        scrollText = "<b>scroll down</b>";
    } else {
        scrollText = "<b>scroll up</b>";
    }

    //console.log("Event: ", evt);
    $("#test").html(scrollText +
      "<br>clientHeight: " + this.clientHeight +
      "<br>scrollHeight: " + this.scrollHeight +
      "<br>scrollTop: " + scrollTop +
      "<br>deltaY: " + deltaY);
});
jherax
  • 5,238
  • 5
  • 38
  • 50
  • 2
    I have a fixed panel view which disables the actual scroll bar, so I needed to detect the direction from the mouse wheel. Your mousewheel solution worked perfectly cross browser so thankyou for that! – Shannon Hochkins Jan 05 '16 at 22:39
8

In case you just want to know if you scroll up or down using a pointer device (mouse or track pad) you can use the deltaY property of the wheel event.

$('.container').on('wheel', function(event) {
  if (event.originalEvent.deltaY > 0) {
    $('.result').append('Scrolled down!<br>');
  } else {
    $('.result').append('Scrolled up!<br>');
  }
});
.container {
  height: 200px;
  width: 400px;
  margin: 20px;
  border: 1px solid black;
  overflow-y: auto;
}
.content {
  height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
  <div class="content">
    Scroll me!
  </div>
</div>

<div class="result">
  <p>Action:</p>
</div>
Yuri
  • 365
  • 6
  • 13
4

Update 2021-04-07

Bobort in a comment (thanks!) pointed to the new note added in the wheel documentation:

Don't confuse the wheel event with the scroll event. The default action of a wheel event is implementation-specific, and doesn't necessarily dispatch a scroll event. Even when it does, the delta* values in the wheel event don't necessarily reflect the content's scrolling direction. Therefore, do not rely on the wheel event's delta* properties to get the scrolling direction. Instead, detect value changes of scrollLeft and scrollTop of the target in the scroll event.

However, the example given in the documentation uses delta to scale, which implies a scroll up for zooming out and scroll down for zooming in.

The code below worked for me in different browsers to detect direction, but given that note, use it at your own risk.

Original answer

Since bind has been deprecated on v3 ("superseded by on") and wheel is now supported, forget wheelDelta:

$(window).on('wheel', function(e) {
  if (e.originalEvent.deltaY > 0) {
    console.log('down');
  } else if (e.originalEvent.deltaY < 0) {
    console.log('up');
  } else if (e.originalEvent.deltaX > 0) {
    console.log('right');
  } else if (e.originalEvent.deltaX < 0) {
    console.log('left');
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 style="white-space:nowrap;overflow:scroll">
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
</h1>

wheel event's Browser Compatibility on MDN's (2019-03-18):

Compatibility of the wheel event

CPHPython
  • 12,379
  • 5
  • 59
  • 71
  • Code above produces two console logs, use the following to fully separate out up/down/left/right: ```if(e.originalEvent.deltaY > 0) { console.log('down'); } else if(e.originalEvent.deltaY < 0) { console.log('up'); } else if(e.originalEvent.deltaX > 0) { console.log('right'); } else if(e.originalEvent.deltaX < 0) { console.log('left'); } ``` – Don Wilson Mar 19 '19 at 00:30
  • For mobile use [`touchmove`](https://developer.mozilla.org/en-US/docs/Web/API/Element/touchmove_event) event instead. – CPHPython Jul 31 '19 at 18:01
  • I checked the documentation, and when detecting the direction of a scroll, it explicitly states the following: "do not rely on the wheel event's `delta*` properties to get the scrolling direction. Instead, detect value changes of `scrollLeft` and `scrollTop` of the target in the scroll event." – Bobort Apr 06 '21 at 20:47
  • 1
    Appreciated @Bobort, I adjusted my answer based on that note. – CPHPython Apr 07 '21 at 09:19
  • @DonWilson thank you! Just updated the answer with your suggestion. – CPHPython Apr 07 '21 at 20:02
3

I have seen many version of good answers here but it seems some folks are having cross browser issues so this is my fix.

I have used this successfully to detect direction in FF, IE and Chrome ... I haven't tested it in safari as I use windows typically.

$("html, body").bind({'mousewheel DOMMouseScroll onmousewheel touchmove scroll': 
    function(e) {
        if (e.target.id == 'el') return;
        e.preventDefault();
        e.stopPropagation();

        //Determine Direction
        if (e.originalEvent.wheelDelta && e.originalEvent.wheelDelta >= 0) {
            //Up
            alert("up");

        } else if (e.originalEvent.detail && e.originalEvent.detail <= 0) {
            //Up
            alert("up");

        } else {
            //Down
            alert("down");
        }
    }
});

Keep in mind I also use this to stop any scrolling so if you want scrolling to still occur you must remove the e.preventDefault(); e.stopPropagation();

GoreDefex
  • 1,461
  • 2
  • 17
  • 41
3

To ignore any snap / momentum / bounce back at the top and bottom of the page, here is a modified version of Josiah's accepted answer:

var prevScrollTop = 0;
$(window).scroll(function(event){

    var scrollTop = $(this).scrollTop();

    if ( scrollTop < 0 ) {
        scrollTop = 0;
    }
    if ( scrollTop > $('body').height() - $(window).height() ) {
        scrollTop = $('body').height() - $(window).height();
    }

    if (scrollTop >= prevScrollTop && scrollTop) {
        // scrolling down
    } else {
        // scrolling up
    }

    prevScrollTop = scrollTop;
});
Community
  • 1
  • 1
Andrew Tibbetts
  • 2,874
  • 3
  • 23
  • 28
3

You can determin mousewhell direction.

$(window).on('mousewheel DOMMouseScroll', function (e) {
    var delta = e.originalEvent.wheelDelta ? 
                   e.originalEvent.wheelDelta : -e.originalEvent.detail;

    if (delta >= 0) {
        console.log('scroll up');
    } else {
        console.log('scroll down');
    }
});
J. Kovacevic
  • 193
  • 16
3
var tempScrollTop, currentScrollTop = 0; 

$(window).scroll(function(){ 

   currentScrollTop = $("#div").scrollTop(); 

   if (tempScrollTop > currentScrollTop ) {
       // upscroll code
   }
  else if (tempScrollTop < currentScrollTop ){
      // downscroll code
  }

  tempScrollTop = currentScrollTop; 
} 

or use the mousewheel extension, see here.

Adam
  • 43,763
  • 16
  • 104
  • 144
3

Use this to find the scroll direction. This is only to find the direction of the Vertical Scroll. Supports all cross browsers.

    var scrollableElement = document.getElementById('scrollableElement');

    scrollableElement.addEventListener('wheel', findScrollDirectionOtherBrowsers);

    function findScrollDirectionOtherBrowsers(event){
        var delta;

        if (event.wheelDelta){
            delta = event.wheelDelta;
        }else{
            delta = -1 * event.deltaY;
        }

        if (delta < 0){
            console.log("DOWN");
        }else if (delta > 0){
            console.log("UP");
        }

    }

Example

Vasi
  • 1,147
  • 9
  • 16
3

this code work fine with IE, Firefox, Opera and Chrome:

$(window).bind('wheel mousewheel', function(event) {
      if (event.originalEvent.deltaY >= 0) {
          console.log('Scroll down');
      }
      else {
          console.log('Scroll up');
      }
  });

'wheel mousewheel' and the property deltaY must be use in bind() function.

Remember : You're user must update their system and browsers for security reasons. In 2018, the excuses of "I have IE 7" is a nonsense. We must educate users.

Have a good day :)

  • 1
    I tried your code and it's the other way. First one is triggered when scrolling down and second one when scrolling up. – AlexioVay Dec 12 '18 at 15:44
  • Hi :) Thanks AlexioVay. I edited my code (About time too!) ^^. Of course "console.log('.......')" it's just an exemple of what we can do. – Cyril Morales Jul 01 '19 at 14:18
2

Keep it super simple:

jQuery Event Listener Way:

$(window).on('wheel', function(){
  whichDirection(event);
});

Vanilla JavaScript Event Listener Way:

if(window.addEventListener){
  addEventListener('wheel', whichDirection, false);
} else if (window.attachEvent) {
  attachEvent('wheel', whichDirection, false);
}

Function Remains The Same:

function whichDirection(event){
  console.log(event + ' WheelEvent has all kinds of good stuff to work with');
  var scrollDirection = event.deltaY;
  if(scrollDirection === 1){
    console.log('meet me at the club, going down', scrollDirection);
  } else if(scrollDirection === -1) {
    console.log('Going up, on a tuesday', scrollDirection);
  }
}

I wrote a more indepth post on it here ​​​​​​​

frzsombor
  • 2,274
  • 1
  • 22
  • 40
CR Rollyson
  • 1,521
  • 1
  • 13
  • 12
2

You can use both scroll and mousewheel option to track up and down movement at once.

 $('body').bind('scroll mousewheel', function(event) {

if (event.originalEvent.wheelDelta >= 0) {
      console.log('moving down');   
    }
    else {
      console.log('moving up'); 
    }
});

You can replace 'body' with (window) as well.

1

stock an increment in the .data () of element scrolled, you will then be able to test number of times the scroll reached top.

Robert
  • 5,278
  • 43
  • 65
  • 115
Spacefrog
  • 11
  • 1
1

Why nobody use the event object returned by jQuery on scroll ?

$window.on('scroll', function (event) {
    console.group('Scroll');
    console.info('Scroll event:', event);
    console.info('Position:', this.pageYOffset);
    console.info('Direction:', event.originalEvent.dir); // Here is the direction
    console.groupEnd();
});

I'm using chromium and I didn't checked on other browsers if they have the dir property.

Jiab77
  • 349
  • 3
  • 11
1

You can use this as well

$(document).ready(function(){

  var currentscroll_position = $(window).scrollTop();
$(window).on('scroll', function(){
Get_page_scroll_direction();
});

function Get_page_scroll_direction(){
  var running_scroll_position = $(window).scrollTop();
  if(running_scroll_position > currentscroll_position) {
      
      $('.direction_value').text('Scrolling Down Scripts');

  } else {
       
       $('.direction_value').text('Scrolling Up Scripts');

  }
  currentscroll_position = running_scroll_position;
}

});
.direction_value{
  position: fixed;
  height: 30px;
  background-color: #333;
  color: #fff;
  text-align: center;
  z-index: 99;
  left: 0;
  top: 0;
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="direction_value">
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi ducimus expedita facilis architecto fugiat veniam natus suscipit amet beatae atque, enim recusandae quos, magnam, perferendis accusamus cumque nemo modi unde!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi ducimus expedita facilis architecto fugiat veniam natus suscipit amet beatae atque, enim recusandae quos, magnam, perferendis accusamus cumque nemo modi unde!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi ducimus expedita facilis architecto fugiat veniam natus suscipit amet beatae atque, enim recusandae quos, magnam, perferendis accusamus cumque nemo modi unde!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi ducimus expedita facilis architecto fugiat veniam natus suscipit amet beatae atque, enim recusandae quos, magnam, perferendis accusamus cumque nemo modi unde!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi ducimus expedita facilis architecto fugiat veniam natus suscipit amet beatae atque, enim recusandae quos, magnam, perferendis accusamus cumque nemo modi unde!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi ducimus expedita facilis architecto fugiat veniam natus suscipit amet beatae atque, enim recusandae quos, magnam, perferendis accusamus cumque nemo modi unde!</p>
arvinda kumar
  • 679
  • 8
  • 6
0

in the .data() of the element you can store a JSON and test values to launch events

{ top : 1,
   first_top_event: function(){ ...},
   second_top_event: function(){ ...},
   third_top_event: function(){ ...},
   scroll_down_event1: function(){ ...},
   scroll_down_event2: function(){ ...}
}
Spacefrog
  • 11
  • 1
0

This is simple and easy detection for when the user scrolls away from the top of the page and for when they return to the top.

$(window).scroll(function() {
    if($(window).scrollTop() > 0) {
        // User has scrolled
    } else {
        // User at top of page
    }
});
Kbam7
  • 324
  • 2
  • 15
0

This is an optimal solution for detecting the direction just when the user end scrolling.

var currentScrollTop = 0 ;

$(window).bind('scroll', function () {     

    scrollTop = $(this).scrollTop();

    clearTimeout($.data(this, 'scrollTimer'));
    $.data(this, 'scrollTimer', setTimeout(function() {

        if(scrollTop > currentScrollTop){
            // downscroll code
            $('.mfb-component--bl').addClass('mfbHide');
        }else{
            // upscroll code
            $('.mfb-component--bl').removeClass('mfbHide');
        }
        currentScrollTop = scrollTop;

    }, 250));

});
Mahmoud
  • 868
  • 11
  • 27
0

You Should try this

var scrl
$(window).scroll(function(){
        if($(window).scrollTop() < scrl){
            //some code while previous scroll
        }else{
            if($(window).scrollTop() > 200){
                //scroll while downward
            }else{//scroll while downward after some specific height
            }
        }
        scrl = $(window).scrollTop();
    });
Rob
  • 26,989
  • 16
  • 82
  • 98
thakurdev
  • 420
  • 4
  • 7
0

I had problems with elastic scrolling (scroll bouncing, rubber-banding). Ignoring the down-scroll event if close to the page top worked for me.

var position = $(window).scrollTop();
$(window).scroll(function () {
    var scroll = $(window).scrollTop();
    var downScroll = scroll > position;
    var closeToTop = -120 < scroll && scroll < 120;
    if (downScroll && !closeToTop) {
        // scrolled down and not to close to top (to avoid Ipad elastic scroll-problems)
        $('.top-container').slideUp('fast');
        $('.main-header').addClass('padding-top');
    } else {
        // scrolled up
        $('.top-container').slideDown('fast');
        $('.main-header').removeClass('padding-top');
    }
    position = scroll;
});
uggeh
  • 713
  • 4
  • 6
0

This works in all pc or phones browsers, expanding on the top answers. One can build a more complex event object window["scroll_evt"] then call it in the handleScroll() function. This one triggers for 2 concurrent conditions, if certain delay has elapsed or certain delta is passed to eliminate some unwanted triggers.

window["scroll_evt"]={"delta":0,"delay":0,"direction":0,"time":Date.now(),"pos":$(window).scrollTop(),"min_delta":120,"min_delay":10};
$(window).scroll(function() {

    var currentScroll = $(this).scrollTop();
    var currentTime = Date.now();
    var boolRun=(window["scroll_evt"]["min_delay"]>0)?(Math.abs(currentTime - window["scroll_evt"]["time"])>window["scroll_evt"]["min_delay"]):false;
    boolRun = boolRun && ((window["scroll_evt"]["min_delta"]>0)?(Math.abs(currentScroll - window["scroll_evt"]["pos"])>window["scroll_evt"]["min_delta"]):false);
    if(boolRun){
        window["scroll_evt"]["delta"] = currentScroll - window["scroll_evt"]["pos"];
        window["scroll_evt"]["direction"] = window["scroll_evt"]["delta"]>0?'down':'up';
        window["scroll_evt"]["delay"] =currentTime - window["scroll_evt"]["time"];//in milisecs!!!
        window["scroll_evt"]["pos"] = currentScroll;
        window["scroll_evt"]["time"] = currentTime;
        handleScroll();
    }
});


function handleScroll(){
    event.stopPropagation();
    //alert(window["scroll_evt"]["direction"]);
    console.log(window["scroll_evt"]);
}
Dexterial
  • 19
  • 3