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

时间:2018-02-09 13:01:03

标签: javascript html css scroll mousewheel

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

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

为了更清楚,网页包装器就像一个“L”。它与this网站的运动方式相同:“我们至少占据了300%”。

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

1 个答案:

答案 0 :(得分:0)

在正常情况下,我会给出正常的关于“你有什么尝试,展示东西”的内容,你应该完全遵循Stack Overflow:How do I ask a good question?

那就是说,这是一个特别有趣的问题,所以我决定采取刺。

我建议在点击“运行代码段”后以完整页面模式查看示例:

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>

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

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

如果我们的scrollX / scrollLeft0,我们会将其添加到scrollY / scrollTop。然后,当我们触底时,我们会检查是否有额外的滚动。如果我们有,我们会将其添加到scrollX

如果我们的scrollX不为零,那么我们只需直接添加任何滚动条。如果它小于零,我们将其设置为零,并将额外值提供给scrollY,以便它可以恢复。

由于deltaY将为负数或正数,因此我们无需进行任何特殊数学处理即可。

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