[javascript] Detecting scroll direction

So I am trying to use the JavaScript on scroll to call a function. But I wanted to know if I could detect the direction of the the scroll without using jQuery. If not then are there any workarounds?

I was thinking of just putting a 'to top' button but would like to avoid that if I could.

I have now just tried using this code but it didn't work:

if document.body.scrollTop <= 0 {
    alert ("scrolling down")
} else {
    alert ("scrolling up")
}

This question is related to javascript scroll onscroll

The answer is


You can try doing this.

_x000D_
_x000D_
function scrollDetect(){_x000D_
  var lastScroll = 0;_x000D_
_x000D_
  window.onscroll = function() {_x000D_
      let currentScroll = document.documentElement.scrollTop || document.body.scrollTop; // Get Current Scroll Value_x000D_
_x000D_
      if (currentScroll > 0 && lastScroll <= currentScroll){_x000D_
        lastScroll = currentScroll;_x000D_
        document.getElementById("scrollLoc").innerHTML = "Scrolling DOWN";_x000D_
      }else{_x000D_
        lastScroll = currentScroll;_x000D_
        document.getElementById("scrollLoc").innerHTML = "Scrolling UP";_x000D_
      }_x000D_
  };_x000D_
}_x000D_
_x000D_
_x000D_
scrollDetect();
_x000D_
html,body{_x000D_
  height:100%;_x000D_
  width:100%;_x000D_
  margin:0;_x000D_
  padding:0;_x000D_
}_x000D_
_x000D_
.cont{_x000D_
  height:100%;_x000D_
  width:100%;_x000D_
}_x000D_
_x000D_
.item{_x000D_
  margin:0;_x000D_
  padding:0;_x000D_
  height:100%;_x000D_
  width:100%;_x000D_
  background: #ffad33;_x000D_
}_x000D_
_x000D_
.red{_x000D_
  background: red;_x000D_
}_x000D_
_x000D_
p{_x000D_
  position:fixed;_x000D_
  font-size:25px;_x000D_
  top:5%;_x000D_
  left:5%;_x000D_
}
_x000D_
<div class="cont">_x000D_
  <div class="item"></div>_x000D_
  <div class="item red"></div>_x000D_
  <p id="scrollLoc">0</p>_x000D_
</div>
_x000D_
_x000D_
_x000D_


Simple code

// Events
$(document).on('mousewheel DOMMouseScroll', "element", function(e) {
    let delta = e.originalEvent.wheelDelta;
    
    if (delta > 0 || e.originalEvent.detail < 0) upScrollFunction();
    if (delta < 0 || e.originalEvent.detail > 0) donwScrollFunction();
}

While the accepted answer works, it is worth noting that this will fire at a high rate. This can cause performance issues for computationally expensive operations.

The recommendation from MDN is to throttle the events. Below is a modification of their sample, enhanced to detect scroll direction.

Modified from: https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event

// ## function declaration
function scrollEventThrottle(fn) {
  let last_known_scroll_position = 0;
  let ticking = false;
  window.addEventListener("scroll", function () {
    let previous_known_scroll_position = last_known_scroll_position;
    last_known_scroll_position = window.scrollY;
    if (!ticking) {
      window.requestAnimationFrame(function () {
        fn(last_known_scroll_position, previous_known_scroll_position);
        ticking = false;
      });
      ticking = true;
    }
  });
}

// ## function instantiation
scrollEventThrottle((scrollPos, previousScrollPos) => {
    if (previousScrollPos > scrollPos) {
      console.log("going up");
    } else {
      console.log("going down");
    }
});


  1. Initialize an oldValue
  2. Get the newValue by listening to the event
  3. Subtract the two
  4. Conclude from the result
  5. Update oldValue with the newValue

// Initialization

let oldValue = 0;

//Listening on the event

window.addEventListener('scroll', function(e){

    // Get the new Value
    newValue = window.pageYOffset;

    //Subtract the two and conclude
    if(oldValue - newValue < 0){
        console.log("Up");
    } else if(oldValue - newValue > 0){
        console.log("Down");
    }

    // Update the old value
    oldValue = newValue;
});

This is an addition to what prateek has answered.There seems to be a glitch in the code in IE so i decided to modify it a bit nothing fancy(just another condition)

$('document').ready(function() {
var lastScrollTop = 0;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
       console.log("down")
   }
   else if(st == lastScrollTop)
   {
     //do nothing 
     //In IE this is an important condition because there seems to be some instances where the last scrollTop is equal to the new one
   }
   else {
      console.log("up")
   }
   lastScrollTop = st;
});});

Simple way to catch all scroll events (touch and wheel)

window.onscroll = function(e) {
  // print "false" if direction is down and "true" if up
  console.log(this.oldScroll > this.scrollY);
  this.oldScroll = this.scrollY;
}

This simple code would work: Check the console for results.

let scroll_position = 0;
let scroll_direction;

window.addEventListener('scroll', function(e){
    scroll_direction = (document.body.getBoundingClientRect()).top > scroll_position ? 'up' : 'down';
    scroll_position = (document.body.getBoundingClientRect()).top;
    console.log(scroll_direction);
});

You can get the scrollbar position using document.documentElement.scrollTop. And then it is simply matter of comparing it to the previous position.


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.body; //document.getElementById('scrollableElement');

scrollableElement.addEventListener('wheel', checkScrollDirection);

function checkScrollDirection(event) {
  if (checkScrollDirectionIsUp(event)) {
    console.log('UP');
  } else {
    console.log('Down');
  }
}

function checkScrollDirectionIsUp(event) {
  if (event.wheelDelta) {
    return event.wheelDelta > 0;
  }
  return event.deltaY < 0;
}

Example


I personally use this code to detect scroll direction in javascript... Just you have to define a variable to store lastscrollvalue and then use this if&else

let lastscrollvalue;

function headeronscroll() {

    // document on which scroll event will occur
    var a = document.querySelector('.refcontainer'); 

    if (lastscrollvalue == undefined) {

        lastscrollvalue = a.scrollTop;

        // sets lastscrollvalue
    } else if (a.scrollTop > lastscrollvalue) {

        // downscroll rules will be here
        lastscrollvalue = a.scrollTop;

    } else if (a.scrollTop < lastscrollvalue) {

        // upscroll rules will be here
        lastscrollvalue = a.scrollTop;

    }
}