Использование scrollTo()
на контейнере, в вашем случае document.documentElement
, создает довольно убедительный клон стандартного вертикального пробела прокрутки.
Если вы реализуете это на полной странице, которая отличается от вашего примера, вы должны позаботиться о том, чтобы изменить container
на соответствующий элемент и изменить window.innerWidth
, если разделы привязки прокрутки не равны 100vw
.
// Set wrapAround to true to go back to 1 after 3
let scrollAmount = 0, wrapAround = true;
const container = document.documentElement;
window.onload = () => {
document.body.onkeyup = (event) => {
switch (event.code) {
case 'Space': {
scrollAmount += window.innerWidth
if (wrapAround && scrollAmount >= container.scrollWidth) {
scrollAmount = window.innerWidth * -1;
}
break;
}
case 'End': {
scrollAmount = container.scrollWidth;
break;
}
case 'Home': {
scrollAmount = 0;
break;
}
case 'PageDown': {
scrollAmount += window.innerWidth
if (wrapAround && scrollAmount >= container.scrollWidth) {
scrollAmount = window.innerWidth * -1;
}
break;
}
case 'PageUp': {
scrollAmount -= window.innerWidth
if (wrapAround && scrollAmount < 0) {
scrollAmount = container.scrollWidth;
}
break;
}
}
container.scrollTo({
top: 0,
left: scrollAmount,
behavior: 'smooth'
});
}
}
// Reset the scrollAmount if the user scrolls back manually
// If we wouldn't do this it would jump from 1 to 3 if the
// user scrolls back from 3 to 1 and presses space
window.onscroll = (event) => {
scrollAmount = container.scrollLeft;
};
* {
margin: 0;
padding: 0
}
html { height: 100% }
html, body, section {
display: flex;
flex-grow: 1
}
body {
scroll-snap-type: x mandatory;
scroll-snap-points-x: repeat(100%);
overflow-x: auto;
}
section {
display: grid;
place-items: center;
flex: 1 0 100%;
scroll-snap-align: center
}
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>