如何在网页中同时垂直和水平滚动鼠标滚轮?
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
事件。任何时候它发生,我们都需要将它添加到 scrollLeft
或 scrollTop
。
如果我们的 scrollX
/scrollLeft
是 0
,那么我们会将其添加到 scrollY
/scrollTop
。然后,当我们到达底部时,我们检查是否有任何额外的滚动。如果有的话,我们会将其添加到 scrollX
.
如果我们的 scrollX
不为零,那么我们将直接向其添加任何卷轴。如果它变得小于零,我们会将其设置为零并将额外的部分提供给 scrollY
以便它可以恢复。
由于 deltaY
将是负数或正数,我们无需进行任何特殊数学运算即可处理它。
对于 CSS,唯一重要的一点是 root
元素隐藏了 overflow
。如果您使用 window,请将 html
设置为 overflow: hidden
。 "content" 然后需要有一些宽度。您不必明确设置它,因为您的内容会为其指定大小。
我们的网页一直垂直滚动到底部,此时我们希望它开始水平滚动。
它也应该反向工作,这样当用户到达水平滚动的末端时,用户可以使用鼠标滚轮回到顶部,沿着相同的路径返回。
为了更清楚,网页包装器就像一个 "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
事件。任何时候它发生,我们都需要将它添加到 scrollLeft
或 scrollTop
。
如果我们的 scrollX
/scrollLeft
是 0
,那么我们会将其添加到 scrollY
/scrollTop
。然后,当我们到达底部时,我们检查是否有任何额外的滚动。如果有的话,我们会将其添加到 scrollX
.
如果我们的 scrollX
不为零,那么我们将直接向其添加任何卷轴。如果它变得小于零,我们会将其设置为零并将额外的部分提供给 scrollY
以便它可以恢复。
由于 deltaY
将是负数或正数,我们无需进行任何特殊数学运算即可处理它。
对于 CSS,唯一重要的一点是 root
元素隐藏了 overflow
。如果您使用 window,请将 html
设置为 overflow: hidden
。 "content" 然后需要有一些宽度。您不必明确设置它,因为您的内容会为其指定大小。