Reputation: 4789
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
Reputation: 192317
Add limits that will stop you from incrementing scrollAmount
if you're at the start or the end:
scrollAmount
is 0scrollAmount
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