如何在网页中同时垂直和水平滚动鼠标滚轮?

How to have both vertical and horizontal mousewheel scroll in the webpage?

我们的网页一直垂直滚动到底部,此时我们希望它开始水平滚动。

它也应该反向工作,这样当用户到达水平滚动的末端时,用户可以使用鼠标滚轮回到顶部,沿着相同的路径返回。

为了更清楚,网页包装器就像一个 "L"。这与 this 网站到达的移动相同:"We've taken on at least 300%".

我看过有关水平滚动的有用建议,但我无法将其实现到垂直滚动。

在正常情况下,我会给出关于 "what have you tried, show stuff" 的正常提示,您一定要在 Stack Overflow 上关注:How do I ask a good question?

也就是说,这是一个特别有趣的问题,所以我决定试一试。

我建议在点击 "Run code snippet":

后以整页模式查看示例

const root = document.getElementById('root');
const content = document.getElementById('content');

root.addEventListener('wheel', e => {
  e.preventDefault();
  e.stopPropagation();
  
  const delta = e.deltaY;
  
  const maxScrollY = content.offsetHeight - root.offsetHeight;
  const maxScrollX = content.offsetWidth - root.offsetWidth;
  
  let scrollY = root.scrollTop;
  let scrollX = root.scrollLeft;
  
  if (scrollX > 0) {
    scrollX += delta;
    
    if (scrollX < 0) {
      scrollY -= scrollX;
      scrollX = 0;
    }
  } else {
    scrollY += delta;
  
    const overflow = scrollY - maxScrollY;
    if (overflow > 0) {
      scrollX += overflow;
      scrollY = maxScrollY;
    } else {
      scrollX = 0;
    }
  }
  
  root.scrollTo(scrollX, scrollY);
});
#root {
  width: 500px;
  height: 500px;
  overflow: hidden;
}

#content {
  width: 5000px;
  height: 1000px;
}

/* This is just to have something in content so we can see it moving */
#content {
  border: 50px solid #F00;
  background-image: 
    linear-gradient(0deg, rgba(0, 0, 255, .5) 0%, rgba(0, 0, 255, .5) 50%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(90deg, #000 0%, #000 50%, #FFF 50%, #FFF 100%);
  background-repeat: repeat;
  background-size: 1% 5%;
}
<div id="root">
  <div id="content"></div>
</div>

此解决方案要求您有两个元素,一个外部 "root" 和一个内部 "content"。 window 应该是 "root" 元素(只需将其切换为 const root = window;)。

基本上,我们然后劫持根元素上的 wheel 事件。任何时候它发生,我们都需要将它添加到 scrollLeftscrollTop

如果我们的 scrollX/scrollLeft0,那么我们会将其添加到 scrollY/scrollTop。然后,当我们到达底部时,我们检查是否有任何额外的滚动。如果有的话,我们会将其添加到 scrollX.

如果我们的 scrollX 不为零,那么我们将直接向其添加任何卷轴。如果它变得小于零,我们会将其设置为零并将额外的部分提供给 scrollY 以便它可以恢复。

由于 deltaY 将是负数或正数,我们无需进行任何特殊数学运算即可处理它。

对于 CSS,唯一重要的一点是 root 元素隐藏了 overflow。如果您使用 window,请将 html 设置为 overflow: hidden。 "content" 然后需要有一些宽度。您不必明确设置它,因为您的内容会为其指定大小。