在 vanilla javascript 中,鼠标滚轮上的平滑垂直滚动?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47011055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Smooth vertical scrolling on mouse wheel in vanilla javascript?
提问by Adeel Imran
I am a huge fan for vanilla javascript, currently I am working on a project where I need to implement smooth scrolling on mouse wheel scroll. I want to implement this using vanilla JS. I found a jQuery snippet on doing some research which go like below.
我是 vanilla javascript 的忠实粉丝,目前我正在做一个项目,我需要在鼠标滚轮滚动上实现平滑滚动。我想使用 vanilla JS 来实现这个。我在做一些研究时发现了一个 jQuery 片段,如下所示。
$(window).on('mousewheel DOMMouseScroll', function(e) {
var dir,
amt = 100;
e.preventDefault();
if(e.type === 'mousewheel') {
dir = e.originalEvent.wheelDelta > 0 ? '-=' : '+=';
}
else {
dir = e.originalEvent.detail < 0 ? '-=' : '+=';
}
$('html, body').stop().animate({
scrollTop: dir + amt
},500, 'linear');
});
Can anyone help me out as in how to implement a smooth scroll without using a helper library like jQuery or any other library.
任何人都可以帮助我了解如何在不使用 jQuery 或任何其他库之类的帮助库的情况下实现平滑滚动。
There are many implementations that people have done in jQuery. But I want a best implementation that one can do in vanilla JS. That can implemented anywhere in React, Angular & Vue anywhere.
人们已经在 jQuery 中完成了许多实现。但我想要一个可以在 vanilla JS 中实现的最佳实现。这可以在任何地方在 React、Angular 和 Vue 中的任何地方实现。
回答by Manuel Otto
How about this:
这个怎么样:
function init(){
new SmoothScroll(document,120,12)
}
function SmoothScroll(target, speed, smooth) {
if (target === document)
target = (document.scrollingElement
|| document.documentElement
|| document.body.parentNode
|| document.body) // cross browser support for document scrolling
var moving = false
var pos = target.scrollTop
var frame = target === document.body
&& document.documentElement
? document.documentElement
: target // safari is the new IE
target.addEventListener('mousewheel', scrolled, { passive: false })
target.addEventListener('DOMMouseScroll', scrolled, { passive: false })
function scrolled(e) {
e.preventDefault(); // disable default scrolling
var delta = normalizeWheelDelta(e)
pos += -delta * speed
pos = Math.max(0, Math.min(pos, target.scrollHeight - frame.clientHeight)) // limit scrolling
if (!moving) update()
}
function normalizeWheelDelta(e){
if(e.detail){
if(e.wheelDelta)
return e.wheelDelta/e.detail/40 * (e.detail>0 ? 1 : -1) // Opera
else
return -e.detail/3 // Firefox
}else
return e.wheelDelta/120 // IE,Safari,Chrome
}
function update() {
moving = true
var delta = (pos - target.scrollTop) / smooth
target.scrollTop += delta
if (Math.abs(delta) > 0.5)
requestFrame(update)
else
moving = false
}
var requestFrame = function() { // requestAnimationFrame cross browser
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(func) {
window.setTimeout(func, 1000 / 50);
}
);
}()
}
p{
font-size: 16pt;
margin-bottom: 30%;
}
<body onload="init()">
<h1>Lorem Ipsum</h1>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
</body>
Use it by calling new SmoothScroll(target,speed,smooth)
通过调用使用它 new SmoothScroll(target,speed,smooth)
Arguments:
参数:
- target: the element to be scrolled smoothly - can be a div or
document - speed: the amout of pixels to be scrolled per mousewheel step
- smooth: the smoothness factor, the higher the value, the more smooth.
- 目标:要平滑滚动的元素 - 可以是 div 或
document - speed:鼠标滚轮每一步滚动的像素数量
- smooth:平滑系数,数值越大越平滑。
Thanks to @Phrogz for the mousewheel normalization.
感谢@Phrogz 进行鼠标滚轮标准化。
EDIT: Since Chrome 73 it is required to mark the event listener for the mousewheelevent as non-passive in order to be able to call preventDefault()on it. Thanks to @Fred K for this.
编辑:从 Chrome 73 开始,需要将事件的事件侦听器标记mousewheel为非被动,以便能够调用preventDefault()它。感谢@Fred K 为此。
回答by douxsey
The code you published is almost vanilla js. Just some ajustement
您发布的代码几乎是普通的 js。只是一些调整
if you have some time Take a look at The wheel event
如果你有时间看看车轮事件
here the new thing will be the animate function
这里的新东西将是 animate 函数
// Code goes here
document.addEventListener('wheel',function (event){
//only vertical scroll
if (event.deltaY > 0)
{
event.preventDefault();
smoothScroll(document.documentElement,100,1000)
}
})
function smoothScroll (domElement,pixel,delay)
{
const intervalToRepeat = 25;
const step = (intervalToRepeat * pixel) / delay;
if ( step < pixel)
{
domElement.scrollTop += step;
setTimeout(function (){
smoothScroll(domElement,pixel - step,delay)
},intervalToRepeat);
}
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<h1>Hello Plunker!</h1>
<div style="width:400px;height:200px;" >
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
<br>
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
<br>
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some <br>
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some <br>
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
lorem ipsum some lorem ipsum some lorem ipsum some lorem ipsum some
</div>
</body>
</html>
回答by tnt-rox
A pure JavaScript onscrollevent will work:
纯 JavaScriptonscroll事件将起作用:
var container = document.getElementById('myScrollingSurface');
var lastY = 0;
container.onscroll = function () {
doSomethingCool(container.scrollTop - lastY);
lastY = container.scrollTop;
};
回答by 3Dos
This is a cool lightweight vanillaJS library for scrollbars. Simple-scrollbar
这是一个很酷的轻量级 vanillaJS 滚动条库。简单滚动条
You could use it with or without showing the actual scrollbars.
您可以在显示或不显示实际滚动条的情况下使用它。

