香草javascript中鼠标滚轮上的平滑垂直滚动?
Posted
技术标签:
【中文标题】香草javascript中鼠标滚轮上的平滑垂直滚动?【英文标题】:Smooth vertical scrolling on mouse wheel in vanilla javascript? 【发布时间】:2018-04-11 04:26:28 【问题描述】:我是 vanilla javascript 的忠实粉丝,目前我正在做一个项目,我需要在鼠标滚轮滚动上实现平滑滚动。我想使用 vanilla JS 来实现它。 我在做一些研究时发现了一个 jQuery sn-p,如下所示。
$(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');
);
任何人都可以帮助我,例如如何在不使用 jQuery 或任何其他库之类的辅助库的情况下实现平滑滚动。
人们已经在 jQuery 中完成了许多实现。但我想要一个可以在 vanilla JS 中实现的最佳实现。这可以在任何地方的 React、Angular 和 Vue 中的任何地方实现。
【问题讨论】:
【参考方案1】:这个怎么样:
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>
拨打new SmoothScroll(target,speed,smooth)
使用它
参数:
-
target:要平滑滚动的元素——可以是div或者
document
速度:每个鼠标滚轮滚动的像素数量
步骤
smooth:平滑系数,数值越高越
流畅。
感谢@Phrogz 提供mousewheel normalization。
编辑:从 Chrome 73 开始,需要将 mousewheel
事件的事件侦听器标记为非被动,以便能够在其上调用 preventDefault()
。感谢@Fred K。
【讨论】:
这似乎是迄今为止最好的实现,又好又流畅。感谢您抽出宝贵时间调查此问题。干杯:) 这个解决方案很漂亮! 您好,我非常喜欢您的解决方案,并在 NuxtJS 项目中使用了它。我做了一些修改,并认为我会分享它们;允许作为 ECMAScript 2015 模块加载,不会在滚动条上触发(由于某种原因 DOMMouseScroll 导致此问题),修复了浏览器偏移量阻止您一直滚动到顶部/底部的问题:gist.github.com/SamJakob/c9175a4c2440e1b14b0b8cf7d99d2d24 @JordanBelf 我也有兴趣。我有一个问题,当您第一次使用鼠标然后使用滚动条或其他东西时,滚动会跳动。 @TheTrueTDF 这是我最终使用的代码,我不记得确切,也找不到时间再次分析它,但我记得它涉及用新的更新 pos 变量pos 一旦用户点击一个链接。希望代码对jsfiddle.net/tw0xc1L2有帮助【参考方案2】:您发布的代码几乎是 vanilla js。只是一些调整
如果你有时间看看The wheel event
这里的新功能是动画功能
// 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>
【讨论】:
很好,但是如果已经向下滚动,向上滚动会有问题。此外,繁忙的页面会导致滚动问题。而不是根据距离设置延迟。选择一个小的延迟,比如 5ms,然后每次你的函数运行时检查自上次运行以来的时间戳,并将滚动位置更新为计划滚动时间和滚动距离的一部分,而不仅仅是距离。【参考方案3】:纯 JavaScript onscroll
事件将起作用:
var container = document.getElementById('myScrollingSurface');
var lastY = 0;
container.onscroll = function ()
doSomethingCool(container.scrollTop - lastY);
lastY = container.scrollTop;
;
【讨论】:
以上是关于香草javascript中鼠标滚轮上的平滑垂直滚动?的主要内容,如果未能解决你的问题,请参考以下文章