I need to detect the direction in that a user scrolls - "up" or "down". Based on the code found in this answer: How can I determine the direction of a jQuery scroll event?
I tried to wrap it in a function so it's a bit more differentiated - but unfortunately, it's not working. I think it has something to do with how I return the value, but the direction is always "up". Being fairly new to JavaScript I am having problems solving this issue.
Here is the code:
$(document).ready(function () {
'use strict';
var lastScrollTop = 0,
st,
direction;
function detectDirection() {
st = window.pageYOffset;
if (st > lastScrollTop) {
direction = "down";
} else {
direction = "up";
}
lastScrollTop = st;
return direction;
}
$(window).bind('scroll', function() {
detectDirection();
console.log(detectDirection());
});
});
And I've also set up a Fiddle.
Could you please help me spotting where the problem is?
I need to detect the direction in that a user scrolls - "up" or "down". Based on the code found in this answer: How can I determine the direction of a jQuery scroll event?
I tried to wrap it in a function so it's a bit more differentiated - but unfortunately, it's not working. I think it has something to do with how I return the value, but the direction is always "up". Being fairly new to JavaScript I am having problems solving this issue.
Here is the code:
$(document).ready(function () {
'use strict';
var lastScrollTop = 0,
st,
direction;
function detectDirection() {
st = window.pageYOffset;
if (st > lastScrollTop) {
direction = "down";
} else {
direction = "up";
}
lastScrollTop = st;
return direction;
}
$(window).bind('scroll', function() {
detectDirection();
console.log(detectDirection());
});
});
And I've also set up a Fiddle.
Could you please help me spotting where the problem is?
Share Improve this question edited May 23, 2017 at 11:53 CommunityBot 11 silver badge asked Mar 7, 2013 at 6:33 SvenSven 13.3k29 gold badges97 silver badges156 bronze badges 2- I would recommend moving your function and variable declarations outside of the ready function. I'm not sure if this will solve the problem, but it might be worth a shot. – Adam Plocher Commented Mar 7, 2013 at 6:34
- @AdamPlocher Thanks for the tip, but it didn't help. Still, is there any general advantage of doing this? Maybe performance wise? – Sven Commented Mar 7, 2013 at 6:36
4 Answers
Reset to default 6$(window).bind('scroll', function() {
var dir = detectDirection();
console.log(dir);
});
You were calling detectDirection()
twice during each scroll event. The first one detected the correct direction, but the second one just saw it in the same place, so it returned "up", and that's what you logged.
See what you get with this:
if (st > lastScrollTop) {
direction = "down";
} else if (st < lastScrollTop ){
direction = "up";
} else {
direction = "static";
}
In addition to what Barmar stated, you could get rid of the line (the call) above the console output and just keep:
console.log(detectDirection());
The code as it is will not work since we never update the lastScrollTop, here is the working code...
$(function(config){
var lastScrollTop = 0, // setting initial scrolltop as top of page
direction; // direction of scroll 1)up -1)down 0)static
function detectDirection() {
// current scrollTop can't be cached or in the local global scope
var st = window.pageYOffset;
if (st > lastScrollTop) {
// scrolling down
direction = -1;
} else if (st < lastScrollTop ){
// scrolling up
direction = 1;
} else {
// static
direction = 0;
}
// updated lastscrolltop with new current top
lastScrollTop = st;
// return the direction
return direction;
}`
I used 0 as static/ 1 as scrolling up/ -1 as scrolling down
Hope that helps someone.
I'm providing a new answer because while BarMar's answer solves your immediate problem, the solution doesn't help you structure the code in a way that will enable you to do two things.
Scope the scroll object more broadly, allowing you to access its attributes elsewhere. This would allow you to do something if the scroll position is a certain value.
Improve the performance of the scrolling.
// Your current functionality $(document).ready(function() { var scroll = { down: true, pos: 0 }; var scrollPos; var detectDirection = function() { scrollPos = window.pageYOffset; if (scrollPos > scroll.pos) { scroll.down = true; } else { scroll.down = false; } scroll.pos = scrollPos; }; $(window).on('optimizedScroll', function() { detectDirection(); // Do something based on scroll direction if (scroll.down == true) { // fooFunction(); } else { // barFunction(); } // Do something based on scroll position, // where scrollTrigger is a number if (scroll.pos > scrollTrigger) { // bazFunction(); } }); }); // Improve scroll performance (function() { var throttle = function(type, name, obj) { var obj = obj || window; var running = false; var func = function() { if (running) { return; } running = true; requestAnimationFrame(function() { obj.dispatchEvent(new CustomEvent(name)); running = false; }); }; obj.addEventListener(type, func); }; throttle('scroll', 'optimizedScroll'); })();
Rather than using .bind(), you should use .on(), as per the jQuery .bind() documentation.
The Immediately Invoked Function Expression (IIFE) to improve the scroll performance comes from the MDN documentation for the scroll event.