Skip to content

Instantly share code, notes, and snippets.

@chrsgrffth
Created June 16, 2016 23:15
Show Gist options
  • Save chrsgrffth/ed4de290161310c9d38286254c2d4b2f to your computer and use it in GitHub Desktop.
Save chrsgrffth/ed4de290161310c9d38286254c2d4b2f to your computer and use it in GitHub Desktop.
A header that hides when scrolling down and shows when scrolling up.
# Vendor.
$ = require('jquery')
# Modules.
animation = require('./animation.coffee')
# Cache jQuery objects.
$document = $(document)
$window = $(window)
$header = $('#global-header')
# For the debounce function.
timeout = null
module.exports =
height: null # Header height.
scroll:
currentPos: $window.scrollTop()
previousPos: $window.scrollTop() # Stored when scrolling ends.
end: null # The bottom of the page
distance: 0 # The distance scrolled before the header is shown.
# Recalculates the bottom of the page.
recalculate: ->
@scroll.end = $document.height() - $window.height()
# Show the header.
show: ->
animation.header('in')
# Reset the scroll distance.
@scroll.distance = 0
# Hide the header.
hide: ->
animation.header('out', @height)
# Reset the scroll distancr.
@scroll.distance = 0
init: ->
# Get the height of the header and the bottom of the page.
@height = $header.outerHeight()
@scroll.end = $document.height() - $window.height()
# Watch the scroll event.
$window.on 'scroll', =>
# Set the current scroll position.
@scroll.currentPos = $window.scrollTop()
# The distance scrolled before the header is shown.
# This provides a threshold for cases where the actual scroll may be up
# briefly while the user meant to click or scroll down.
@scroll.distance += Math.abs(@scroll.currentPos - @scroll.previousPos)
# Only run the logic every 10ms.
debounce( =>
# If we're not at the bottom.
if @scroll.currentPos < @scroll.end-50
# If we're scrolling up.
if @scroll.currentPos < @scroll.previousPos
@show() if @scroll.distance > 100
# If we're scrolling down.
else
# And we're past 50px, hide the header.
if @scroll.currentPos > 50
@hide() if @scroll.distance > 25
else
@show()
@show() if @scroll.currentPos <= 10
# If we're at the bottom, show the header.
# else
# @show()
# After we stop scrolling, get the scroll position.
# Used to determine direction of the next scroll event.
@scroll.previousPos = @scroll.currentPos
, 10)
# Define the debounce function.
debounce = (func, wait) ->
clearTimeout(timeout)
timeout = setTimeout ->
func()
, wait
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment