Tzar
Tzar

Reputation: 4789

Key presses get “remembered” when the beginning or the end of the page is reached

I have an entirely horizontally spread page that one can scroll by pressing, for example, Space Bar, Page Down, Right Arrow, Home, End and etc, to navigate.

The problem I have is that if you, for example, press the Page Down key multiple times when you reach the end of the page, it will take you the same number of Page Up presses to scroll back. Same happens at the beginning of the page if you, for example, press the Left Arrow multiple times, and then try to go right afterword.

How can I solve this so that key presses don’t get “remembered” when the beginning or the end of the page is reached?


You can run my code below:

let scrollAmount = 0
const container = document.documentElement

window.onload = () => {
  document.body.onkeydown = event => {
    switch (event.code) {
      case "Space":
      case "PageDown":
      case "ArrowRight":
      case "ArrowDown": {
        event.preventDefault()
        scrollAmount += window.innerWidth
        break
      }
      case "PageUp":
      case "ArrowLeft":
      case "ArrowUp": {
        event.preventDefault()
        scrollAmount -= window.innerWidth
        break
      }
      case "Home": {
        scrollAmount = 0
        break
      }
      case "End": {
        scrollAmount = container.scrollWidth
        break
      }
    }

    container.scrollTo({
      top: 0,
      left: scrollAmount,
      behavior: "smooth"
    })
  }
}

// Reset the scrollAmount if the user scrolls back manually.
window.onscroll = event => {
  scrollAmount = container.scrollLeft
}
* {
  margin: 0;
  padding: 0
}

html { height: 100% }

html, body, section {
  display: flex;
  flex-grow: 1
}

section {
  display: grid;
  place-items: center;
  flex: 1 0 100%
}

section:nth-of-type(1) { background: orange }
section:nth-of-type(2) { background: limeGreen }
section:nth-of-type(3) { background: royalBlue }

h2 { color: white }
<section><h2>1</h2></section>
<section><h2>2</h2></section>
<section><h2>3</h2></section>

Upvotes: 1

Views: 34

Answers (1)

Ori Drori
Ori Drori

Reputation: 192317

Add limits that will stop you from incrementing scrollAmount if you're at the start or the end:

  • Start - scrollAmount is 0
  • End - scrollAmount is equal to the body.scrollWidth - window.innerWidth (the entire width of the body - the width of a page)

let scrollAmount = 0
const container = document.documentElement

window.onload = () => {
  document.body.onkeydown = event => {
    switch (event.code) {
      case "Space":
      case "PageDown":
      case "ArrowRight":
      case "ArrowDown":
        {
          event.preventDefault()
          const maxScroll = container.scrollWidth - window.innerWidth
          if(scrollAmount === maxScroll) return; // if at the end, return
          scrollAmount += window.innerWidth
          break
        }
      case "PageUp":
      case "ArrowLeft":
      case "ArrowUp":
        {
          event.preventDefault()
          
          if(scrollAmount === 0) return; // if at the start return
          scrollAmount -= window.innerWidth
          break
        }
      case "Home":
        {
          scrollAmount = 0
          break
        }
      case "End":
        {
          scrollAmount = container.scrollWidth - window.innerWidth
          break
        }
    }

    container.scrollTo({
      top: 0,
      left: scrollAmount,
      behavior: "smooth"
    })
  }
}

// Reset the scrollAmount if the user scrolls back manually.
window.onscroll = event => {
  scrollAmount = container.scrollLeft
}
* {
  margin: 0;
  padding: 0
}

html { height: 100% }

html, body, section {
  display: flex;
  flex-grow: 1
}

section {
  display: grid;
  place-items: center;
  flex: 1 0 100%;
}

section:nth-of-type(1) { background: orange }
section:nth-of-type(2) { background: limeGreen }
section:nth-of-type(3) { background: royalBlue }

h2 { color: white }
<section>
  <h2>1</h2>
</section>
<section>
  <h2>2</h2>
</section>
<section>
  <h2>3</h2>
</section>

Upvotes: 2

Related Questions