summaryrefslogtreecommitdiff
path: root/assets/js/back2top.js
blob: 6d7501e1d1def258a499a5a42756237fe32ef028 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Back2top, the Batrick
// author: Eltrac

const backToTop = document.getElementById("back2top")
const backToTopButton = document.getElementById("back2top-button")
const backToTopInstruction = document.getElementById("back2top-instruction")
const seenAndUsedBat = localStorage.getItem("geedeapro.ui.seenAndUsedBat")

if (backToTopInstruction && backToTopButton) {
    function hideInstruction() {
        backToTopInstruction.remove()
    }
    if (seenAndUsedBat) hideInstruction()

    // listen to button click and scroll to top
    backToTopButton.addEventListener("click", () => {
      window.scrollTo({ top: 0, behavior: "smooth" })
      if (!seenAndUsedBat) {
        localStorage.setItem("geedeapro.ui.seenAndUsedBat", true);
        hideInstruction();
      }
    })

    // listen to scroll and toggle button visibility
    let lastOffset = window.scrollY

    window.addEventListener("scroll", () => {
      const offset = window.scrollY
      const batIsHidden = backToTop.classList.contains("-top-25")
      const enoughHeight = offset >= 2000
      const isScrollingUp = offset < lastOffset
      const isScrollingDown = offset > lastOffset

      function hide() {
        backToTop.classList.remove("top-0")
        backToTop.classList.add("-top-25")
        backToTop.classList.remove("animate-head-shake")
      }

      function show() {
        backToTop.classList.remove("-top-25")
        backToTop.classList.add("top-0")
        backToTop.classList.add("animate-head-shake")
      }

      if (enoughHeight && isScrollingUp && batIsHidden) {
        // show only when scrolling up
        show()
      } else if (isScrollingDown && !batIsHidden) {
        // hide as soon as user scrolls down again
        hide()
      }

      // hide no matter what if too close to top
      if (!enoughHeight) hide()

      lastOffset = offset
    })
}