简体   繁体   English

在 vanilla javascript 中,鼠标滚轮上的平滑垂直滚动?

[英]Smooth vertical scrolling on mouse wheel in vanilla javascript?

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.我是 vanilla javascript 的忠实粉丝,目前我正在做一个项目,我需要在鼠标滚轮滚动上实现平滑滚动。 I want to implement this using vanilla JS.我想使用 vanilla JS 来实现这个。 I found a jQuery snippet on doing some research which go like below.我在做一些研究时发现了一个 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.人们已经在 jQuery 中完成了许多实现。 But I want a best implementation that one can do in vanilla JS.但我想要一个可以在 vanilla JS 中实现的最佳实现。 That can implemented anywhere in React, Angular & Vue anywhere.这可以在 React、Angular 和 Vue 的任何地方实现。

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:参数:

  1. target: the element to be scrolled smoothly - can be a div or document目标:要平滑滚动的元素 - 可以是 div 或document
  2. speed: the amout of pixels to be scrolled per mousewheel step速度:鼠标滚轮每一步滚动的像素数量
  3. smooth: the smoothness factor, the higher the value, the more smooth. smooth:平滑因子,数值越大越平滑。

Thanks to @Phrogz for the mousewheel normalization .感谢 @Phrogz 进行鼠标滚轮标准化

EDIT: Since Chrome 73 it is required to mark the event listener for the mousewheel event as non-passive in order to be able to call preventDefault() on it.编辑:从 Chrome 73 开始,需要将mousewheel事件的事件侦听器标记为非被动,以便能够对其调用preventDefault() Thanks to @Fred K for this.感谢@Fred K 为此。

The code you published is almost vanilla js.您发布的代码几乎是普通的 js。 Just some ajustement只是一些调整

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>

A pure JavaScript onscroll event will work:纯 JavaScript onscroll事件将起作用:

var container = document.getElementById('myScrollingSurface');
var lastY = 0;
container.onscroll = function () {
  doSomethingCool(container.scrollTop - lastY);
  lastY = container.scrollTop;
};

This is a cool lightweight vanillaJS library for scrollbars. 这是一个非常酷的轻量级vanillaJS库,用于滚动条。 Simple-scrollbar 简单滚动条

You could use it with or without showing the actual scrollbars. 您可以在不显示实际滚动条的情况下使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM