按键时水平滚动整页

Horizontally scrolling by a full page on key press

我有一个完全水平展开的页面,可以通过按下来滚动,例如,Space Bar, Page Down向右箭头主页结束等进行导航。

我目前有两个问题想解决:

  1. 当按右箭头左箭头键时,页面移动略大于100vw,但它的目标是使页面边缘与 window.

  2. 完美对齐
  3. 例如,如果您在到达页面末尾时多次按 Page Down 键,则需要相同次数的 Page Up 按向后滚动。

对于解决此问题的任何帮助,我将不胜感激。

这是我的代码:

let scrollAmount = 0
const container = document.documentElement

window.onload = () => {
  document.body.onkeyup = event => {
    switch (event.code) {
      case "Space":
      case "PageDown":
      case "ArrowRight": {
        scrollAmount += window.innerWidth
        break
      }
      case "PageUp":
      case "ArrowLeft": {
        scrollAmount -= window.innerWidth
        break
      }
      case "Home":
      case "ArrowUp": {
        scrollAmount = 0
        break
      }
      case "End":
      case "ArrowDown": {
        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
}

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>

添加 event.preventDefault() 并将侦听器更改为 keydown 而不是 keyup 将阻止箭头键的默认连续滚动。这是有效的,因为箭头键滚动是在按住时触发的(我们现在已经阻止了),而事件侦听器仅在箭头键被抬起时被触发。

您可以对 HomeEnd 执行相同的操作(添加 event.preventDefault(),即)以防止所有水平滚动.

let scrollAmount = 0
const container = document.documentElement

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

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

// 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
}

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>