1

I'm trying to create a jQuery snippet that enables me to add 4 different classes to a div based on the user's current scroll position.

The desired states are: 1. User is at top of page 2. User is at bottom of page 3. User is scrolling down 4. User is scrolling up

In the below code I have achieved number 1 & 2, but am not able to get 3 & 4 to work.

Can anybody help? Thanks.

// Add/remove classes to navigation based on position
var scrollPosition = $(window).scrollTop();

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

    // User is at bottom of window
    if($(window).scrollTop() + $(window).height() === $(document).height()) {
       $('#global-header').removeClass().addClass('at-bottom');
    // User is at top of window
    } else if ($(window).scrollTop() === 0) {
        $('#global-header').removeClass().addClass('at-top');
    } else {
        $('#global-header').removeClass();
    }
});
3
  • #3 and #4 would involve capturing the previous scroll position, preserving it between scroll events, and comparing it to the new scroll position to know the direction. Commented Apr 19, 2018 at 20:14
  • possible duplicate of stackoverflow.com/questions/9144560/… Commented Apr 19, 2018 at 20:14
  • @Taplar - can you assist with this at all? Commented Apr 19, 2018 at 20:15

2 Answers 2

1

Here you have a working solution capturing the previous solution (as suggested in the comments by @Taplar):

// Add/remove classes to navigation based on position
var scrollPosition = $(window).scrollTop();

var threshold = 12;
var hideHeaderOnScrollDelay = 200;
var lastScrollPosition = 0;
$(window).bind('load scroll', function() {

  // User is at bottom of window
  if ($(window).scrollTop() + $(window).height() >= $(document).height()) {
    $('#global-header').removeClass().addClass('at-bottom');
    // User is at top of window
  } else if ($(window).scrollTop() === 0) {
    $('#global-header').removeClass().addClass('at-top');
  } else {
    if ($(window).scrollTop() - lastScrollPosition > threshold) {
      $('#global-header').removeClass().addClass('at-bottom');
    } else if (lastScrollPosition - $(window).scrollTop() > threshold) {
      $('#global-header').removeClass().addClass('at-top');
    }
  }

  lastScrollPosition = $(window).scrollTop();
});
#global-header {
  position: fixed;
  width: 100%;
  height: 60px;
  background-color: #006688;
  color: white;
  text-align: center;
  line-height: 60px;
  display: none;
}

#global-header.at-top,
#global-header.at-bottom {
  display: block;
}

#global-header.at-bottom {
  bottom: 0px;
}

#content {
  height: 600px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="global-header">HEADER</div>

<div id="content"></div>

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks so much for this, works well! I have simplified to suit my question, as I don't require the automatic hiding of the header. I also want to retain the classes until another class becomes active. Thanks!
Hi @raul.vila - In my answer, are you able to explain exactly what the var lastScrollPosition = 0; and lastScrollPosition = $(window).scrollTop(); are doing? I'd like to explain exactly what purpose they serve, although I know they are required. Thank you!
@dungey_140 It's a simple way to detect the scrolling direction. The scrolling event has no info about it (the wheel event does, but that doesn't work with cursor or pageUp/pageDown navigation) so you can compare the current position with the previous one to see where the user is going. The first initialization to 0 is because the page is loaded at top (anyway the value is set when again load event is fired), and then we keep its value updated after each scroll event.
@dungey_140 I've updated my answer and removed the setTimeout so it matches your requirements. Feel free to mark as solved if that's the case.
One final thought, could it be possible to add a 'scroll threshold' to only activate the scrolling-up and scrolling-down classes if the user has scrolled more than 100px?
|
1

Thanks to @raul.vila for his working solution. This answer is a simplified version with the purpose of adding 4 classes, .at-top, .at-bottom, .scrolling-up and .scrolling-down. It also retains these classes until such point as another class becomes active.

// Add/remove classes to navigation based on position
var lastScrollPosition = 0;

$(window).bind('load scroll', function() {
    // User is at top of window
    if ($(window).scrollTop() === 0) {
        $('#global-header').removeClass().addClass('at-top');
    // User is at bottom of window
    } else if ($(window).scrollTop() + $(window).height() >= $(document).height()) {
        $('#global-header').removeClass().addClass('at-bottom');
    // User is scrolling down
    } else if (lastScrollPosition < $(window).scrollTop()) {
        $('#global-header').removeClass().addClass('scrolling-down');
    // User is scrolling up
    } else {
        $('#global-header').removeClass().addClass('scrolling-up');
    }

    lastScrollPosition = $(window).scrollTop();
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.