【问题标题】:Conflict when simultaneously using keyboard events for scrolling and CSS scroll snapping同时使用键盘事件进行滚动和 CSS 滚动捕捉时发生冲突
【发布时间】:2019-11-26 02:04:33
【问题描述】:

您可以通过按 空格键Page Up / Page DownLeft Arrow / Right Arrow 键水平滚动我的演示页面。您还可以使用鼠标或触控板快速滚动。

但只有一个或另一个有效。

有没有办法让键盘事件和 CSS 滚动捕捉可以共存?我错过了什么?任何帮助都将不胜感激,因为我已经为这个问题苦苦挣扎了一个多星期。


Check out my demo on CodePen

(请取消注释相关的 CSS 代码以启用滚动捕捉效果,以便看到键盘快捷键停止工作。)


import animate from "https://cdn.jsdelivr.net/npm/animateplus@2/animateplus.js"

const sections = Array.from(document.querySelectorAll("section")).sort(
  (s1, s2) => {
    return s1.getBoundingClientRect().left - s2.getBoundingClientRect().left
  }
)

const getSectionInView = () => {
  const halfWidth = window.innerWidth / 2
  const index = sections.findIndex(
    section =>
      section.getBoundingClientRect().left <= halfWidth &&
      section.getBoundingClientRect().right > halfWidth
  )
  return index
}

const getNextSection = dir => {
  const sectionInViewIndex = getSectionInView()
  const nextIndex = sectionInViewIndex + dir
  const numSections = sections.length
  const nextSectionIndex =
    nextIndex < 0 || nextIndex >= numSections ? sectionInViewIndex : nextIndex
  return sections[nextSectionIndex]
}

const container = document.scrollingElement

const animateScroll = dir => {
  const from = container.scrollLeft
  const { left } = getNextSection(dir).getBoundingClientRect()
  return progress => (container.scrollLeft = from + progress * left)
}

window.onload = () => {
  document.body.onkeydown = event => {
    switch (event.key) {
      case " ": // Space Bar
      case "PageDown":
      case "ArrowRight": {      
        animate({
          easing: "out-quintic",
          change: animateScroll(1)
        })
        break
      }
      case "PageUp":
      case "ArrowLeft":  {      
        animate({
          easing: "out-quintic",
          change: animateScroll(-1)
        })
        break
      }
    }
  }
}

注意:我正在使用一个名为Animate Plus 的小而优雅的模块来实现平滑的滚动动画。


更新:@Kostja 的解决方案适用于 Chrome,但不适用于 Mac 或 iOS 的 Safari,对我来说,它适用于 Safari 至关重要。

【问题讨论】:

  • 你的问题解决了吗??我也面临同样的问题...我使用 css 使用平滑滚动...html { scroll-behavior: smooth; } 在使用它时,箭头键在我的页面上没有工作..你能帮忙吗?有没有其他方法可以同时使用这两种东西。或者它有什么错误???
  • @Harshitmishra 不幸的是,没有。好像不能干干净净。
  • 哦...那我可能会看到任何替代方法...谢谢兄弟。

标签: javascript mouseevent keyboard-events scroll-snap animateplus


【解决方案1】:

我猜没有,css 覆盖了 javascript。但是您可以简单地添加轮事件侦听器,例如:

window.addEventListener("wheel", function() {
    if(event.deltaY > 0){
      animate({
        easing: "out-quintic",
        change: animateScroll(1)
      })      
    }
      if(event.deltaY < 0){
      animate({
        easing: "out-quintic",
        change: animateScroll(-1)
      })      
    }      
});

https://codepen.io/kostjaaa/pen/NWWVBKd

【讨论】:

  • 能否请您在 CodePen 上发布一个 fork 的链接,因为我无法让您的解决方案正常工作?谢谢。
  • 是的,已经用 Chrome 版本 78.0.3904.108 (64Bit) 尝试过
  • 什么对您不利?快照还是滚动?顺便说一句,您必须在使用键盘之前单击视图。键盘不像滚动那样与悬停结合使用。
  • 我刚刚在 Chrome 中测试过,它确实有效!但它不适用于 Mac 或 iOS 的 Safari,这对我来说对于这个项目来说更为重要。你知道可能是什么原因吗?
  • 我没有 safari,也许你可以试试 'mousewheel' 而不是 'wheel'?
【解决方案2】:
window.onload = () => {
  window.addEventListener("wheel", () => {
    const direction = event.deltaY > 0 ? 1 : event.deltaY < 0 ? -1 : false;

    if (direction) {
      animate({
        easing: "out-quintic",
        change: animateScroll(direction)
      });
    }
  });

  document.body.onkeydown = event => {
    switch (event.key) {
      case " ": // Space Bar
      case "PageDown":
      case "ArrowRight": {
        animate({
          easing: "out-quintic",
          change: animateScroll(1)
        });
        break;
      }
      case "PageUp":
      case "ArrowLeft": {
        animate({
          easing: "out-quintic",
          change: animateScroll(-1)
        });
        break;
      }
    }
  };
};    

这应该可行。

https://codepen.io/JZ6/pen/XWWQqRK

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 2019-07-14
    • 2011-06-07
    • 2017-07-27
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    相关资源
    最近更新 更多