纯javaScript实现元素平滑滚动,改进前两个版本,支持鼠标滚轮滚动和点击元素滚动,滚动更顺畅
2024-10-03 10:44:22
windowScroll(id, number, distance, direction, obj) 参数介绍: 1.id:所要滚动的元素id; 2.number:滚动次数; 3.distance:每次滚动的距离; 4.direction:滚动的方向(上下传入"top",左右传入"left"); 5.obj:滚动的触发方式(滚轮触发、点击触发); 6.obj格式{touch: click||scroll||click&scroll, control_up: "控制往上滚动的点击元素的id", control_down: "控制页面往下滚动的点击元素的id"} a.touch:什么触发方式,三个选项click/scroll/click&scroll; b.control_up:你的触发页面向上滚动的按钮id; c.control_down:你的触发页面向下滚动的按钮id 7.该方法支持上下滚动和左右滚动 8.无返回值 示例:1.windowScroll("content", 10, 3000, "top", {touch:"scroll"});说明:滚动元素id为content,滚动10次,每次滚动3000px,滚动方向为上下滚动,滚动触发方式为鼠标滚轮触发 2.windowScroll("xxx",20,cHeight,"left",{touch:"click", click_up:"aaa", click_down:"bbb"});说明:滚动元素id为xxx,滚动20次,每次滚动 cHeight(一个变量) px距离,滚动方向为左右滚动,滚动方式为点击滚动,点击id为aaa的元素页面往左滚动,点击id为bbb的元素页面往右滚动touch还有一个值是"click&scroll"作用是即可以通过点击滚动也可以通过鼠标滚轮滚动 前两次版本链接:有兴趣可以对比一下改动的地方在哪里
第二版:对于鼠标滚动事件的补充(1)
最新版如下:
新增功能:
1.可以自定义滚动距离
2.解决了先前版本的滚动时候页面会晃动的问题
3.优化了滚动,实现页面的平滑滚动
附代码:
//使用鼠标滚轮每次滚动自定义大小的距离 function windowScroll(id, number, distance, direction, obj) { var oHtml = document.documentElement; //在IE8以下不支持使用class选取元素 var oContent = document.getElementById(id); //获取文档的高度 var cHeight; if(direction === "top" ) { cHeight = oHtml.clientHeight; }else if( direction === "left" ) { cHeight = oHtml.clientWidth; } //用于控制鼠标每个多长时间才能让页面滚动设置的变量 var count = 1; //用于添加触发点击事件的元素 if(obj.touch === "click" || obj.touch === "click&scroll"){ var oControl_up, oControl_down; oControl_up = document.getElementById(obj.control_up); oControl_down = document.getElementById(obj.control_down); } //在窗口尺寸改变的时候实时给cHeight赋值 window.onresize = function () { if(direction === "top" ) { cHeight = oHtml.clientHeight; }else if( direction === "left" ) { cHeight = oHtml.clientWidth; } }; if(window.addEventListener) { //用于判断当前浏览器是否为FF if( navigator.userAgent.toLowerCase().indexOf("firefox") !== -1 ) { //滚动触发 if(obj.touch === "scroll") { oHtml.addEventListener("DOMMouseScroll", function (e) { //FF浏览器的滚动条滚动上下判断是与其它浏览器相反的,负值是向上滚动 if( count === 1 ) { //滚轮向上滚动时 if( e.detail < 0 ) { upRoll(); } //e.detail是正值说明是想下滚动 else if( e.detail > 0 ) { downRoll(); } } //阻止浏览器页面滚动的默认事件 e.preventDefault(); }, false); } else if( obj.touch === "click" ) { //点击触发的事件,下同 clickTouch(); }else if ( obj.touch === "click&scroll" ) { oHtml.addEventListener("DOMMouseScroll", function (e) { //FF浏览器的滚动条滚动上下判断是与其它浏览器相反的,负值是向上滚动 if( count === 1 ) { //滚轮向上滚动时 if( e.detail < 0 ) { upRoll(); } //e.detail是正值说明是想下滚动 else if( e.detail > 0 ) { downRoll(); } } //阻止浏览器页面滚动的默认事件 e.preventDefault(); }, false); clickTouch(); } } else { if(obj.touch === "scroll") { oHtml.addEventListener('mousewheel',function (e) { var event = e || window.event; //当count = 1 时让页面可以滚动 if( count === 1 ) { //当鼠标向上滚动时 if( event.wheelDelta > 0 ) { upRoll(); } //当鼠标向下滚动时 if( event.wheelDelta < 0 ) { downRoll(); } } //阻止浏览器滚动的默认事件,防止页面来回晃动 event.preventDefault(); }, {passive: false}); } else if( obj.touch === "click" ){ clickTouch(); } else if(obj.touch === "click&scroll"){ oHtml.addEventListener('mousewheel',function (e) { var event = e || window.event; //当count = 1 时让页面可以滚动 if( count === 1 ) { //当鼠标向上滚动时 if( event.wheelDelta > 0 ) { upRoll(); } //当鼠标向下滚动时 if( event.wheelDelta < 0 ) { downRoll(); } } //阻止浏览器滚动的默认事件,防止页面来回晃动 event.preventDefault(); }, {passive: false}); clickTouch(); } } } else if(window.attachEvent) { if(obj.touch === "scroll") { oHtml.attachEvent("onmousewheel",function(){ console.log(count); if( count === 1 ){ //当鼠标向上滚动时 if( event.wheelDelta > 0 ) { upRoll(); } //当鼠标向下滚动时 if( event.wheelDelta < 0 ) { downRoll(); } } //阻止浏览器滚动的默认事件,防止页面来回晃动 return false; }); } else if ( obj.touch === "click" ) { clickTouch(); } else if( obj.touch === "click&scroll" ) { oHtml.attachEvent("onmousewheel",function(){ console.log(count); if( count === 1 ){ //当鼠标向上滚动时 if( event.wheelDelta > 0 ) { upRoll(); } //当鼠标向下滚动时 if( event.wheelDelta < 0 ) { downRoll(); } } //阻止浏览器滚动的默认事件,防止页面来回晃动 return false; }); clickTouch(); } } //向上滚动时执行的函数 function upRoll(){ if( getElemProp(oContent, direction) >= 0 ) { console.log("到顶了"); console.log(getElemProp(oContent,direction)); } else { elemDisplace(oContent, direction, 1, distance); //如果鼠标不是在顶部往上滚动的话就将count++ count++; } } //向下滚动时执行的函数 function downRoll() { //判断是否滚动到底部 if( getElemProp(oContent, direction) <= -number*cHeight ) { console.log("到底了"); } else { elemDisplace(oContent, direction, -1, distance); //如果鼠标不是在顶部往上滚动的话就将count++ count++; } } //给点击元素添加点击事件 function clickTouch(){ if(oControl_down && oControl_up){ eventBinding(oControl_up, 'click', function(){ if( count === 1 ) { upRoll(); } }); eventBinding(oControl_down, 'click', function(){ if( count === 1 ) { downRoll(); } }); } else { alert("oControl_up或oControl_down未传入"); } } //让元素加速运动 function elemDisplace(elem, direction, speed, distance){ //记录元素当前的位置 var origin = parseInt( getElemProp(elem, direction) ); var pos; //定义一个x用于停止动画,因为缓冲动画的speed会有一个误差 var x = distance/150; //将distance转换成数字 var numDistance = parseInt(distance); var Timer = setInterval(function(){ pos = parseInt( getElemProp(elem, direction) ); //判断元素是否位移到了指定的地方 if( Math.abs( pos - origin ) >= numDistance - 1.5 ){ if(speed > 0){ elem.style[direction] = origin + numDistance + 'px'; }else { elem.style[direction] = origin - numDistance + 'px'; } speed = 0; count = 1; clearInterval(Timer); console.log("停止时:speed" + speed + " , pos" + pos); }else { //判断元素的位移方向,判断初始速度是否为1/-1,如果为1则置为2/-2 if(Math.abs( speed ) === 1) { if(speed > 0 ) { speed = 2; } else { speed = -2; } } else { if(Math.abs( pos - origin ) <= numDistance/2 ){ //前二分之一路程加速 speed *= 1.1; } else { //后面减速 speed /= 1.1; if( speed > -1 && speed < 0) { speed = -1.01; } else if ( speed < 1 && speed > 0) { speed = 1.01; } //当速度大于剩余距离时手动将其速度降低,防止页面抖动 if( numDistance - Math.abs( pos - origin ) < Math.abs( speed ) && Math.abs( speed ) > 2 ){ if( speed < 0 ) { speed = -2; } else if ( speed > 0 ){ speed = 2; } } } } elem.style[direction] = pos + speed + 'px'; console.log("运动时:pos - origin:" + Math.abs( pos - origin ) + " ,numDistance/2:" + numDistance/2 + ' ,' + ' speed:' + speed); } },15); } //获取元素属性 function getElemProp(elem, prop){ if(window.getComputedStyle){ return parseInt(window.getComputedStyle(elem, null)[prop]); }else{ return parseInt(elem.currentStyle[prop]); } } //给元素绑定事件 function eventBinding(elem, type, fn){ if(elem.addEventListener){ elem.addEventListener(type, fn, false); }else if(elem.attachEvent){ elem.attachEvent('on' + type, function () { fn.call(elem); }); }else{ elem['on' + type] = fn; } } }
注:使用的时候注意给需要滚动的元素设置定位属性
欢迎大家对方法不足的地方提出建议
原创文章
最新文章
- 在Asp.Net中操作PDF – iTextSharp - 使用表格
- SharePoint 2013 托管导航 无法被开启的解决办法
- 使用CuteSlider做网站炫酷的幻灯片
- 在centos6.5中安装jdk
- iOS学习笔记---c语言第十一天
- 未指定的错误,发生了一个 Oracle 错误,但无法从 Oracle 中检索错误信息。数据类型不被支持。
- [Angular 2] Router basic and Router Params
- Devexpress之barManager控件属性
- Android OpenGL 入门示例----绘制三角形和正方形
- Redola.Rpc 集成 Consul 服务发现
- maven使用jstl表达式和The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application解决
- hdu-1052(贪心)
- C#: int 与 byte[] 互转
- PHP匿名函数
- 浅谈java中bigInteger用法
- ST_Geometry效率的测试与分析
- Scrapy运行流程
- shell脚本之特殊符号总结性梳理
- bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块
- 《转》推荐几个精致的web UI框架