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"作用是即可以通过点击滚动也可以通过鼠标滚轮滚动

前两次版本链接:有兴趣可以对比一下改动的地方在哪里

第一版:纯JS阻止浏览器默认滚动事件,实现自定义滚动方法

第二版:对于鼠标滚动事件的补充(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;
        }
    }
}

 注:使用的时候注意给需要滚动的元素设置定位属性


欢迎大家对方法不足的地方提出建议
原创文章

纯javaScript实现元素平滑滚动,改进前两个版本,支持鼠标滚轮滚动和点击元素滚动,滚动更顺畅的更多相关文章

  1. 如何让DbGrid支持鼠标滚轮滚动

    如何让DbGrid支持鼠标滚轮滚动 在主窗体上加一个ApplicationEvents控件(控件在Additional面板中), 在它的OnMessage事件中加入下述代码,一切搞定-! proced ...

  2. jq点击改变元素样式、添加类,显示隐藏,图标旋转,再次点击还原;表格点击显示下拉详情

    点击前 点击后 <tr> <td class="right" data-id="{$vo.id}" id="{$vo.id}&quo ...

  3. 横纵方向走马灯滚动,纯javascript代码

    <body onload="beginmarquee()"> <table width="1024" border="0" ...

  4. 【javascript常见面试题】常见前端面试题及答案

    转自:http://www.cnblogs.com/syfwhu/p/4434132.html 前言 本文是在GitHub上看到一个大牛总结的前端常见面试题,很多问题问的都很好,很经典.很有代表性.上 ...

  5. 纯javaScript、jQuery实现个性化图片轮播

    纯javaScript实现个性化图片轮播 轮播原理说明<如上图所示>: 1. 画布部分(可视区域)属性说明:overflow:hidden使得超出画布部分隐藏或说不可见.position: ...

  6. 纯JavaScript实现页面行为的录制

    在网上有个开源的rrweb项目,该项目采用TypeScript编写(不了解该语言的可参考之前的<TypeScript躬行记>),分为三大部分:rrweb-snapshot.rrweb和rr ...

  7. javascript日历控件——纯javascript版

    平时只有下班时间能code,闲来写了个纯javascript版.引用该calendar.js文件,然后给要设置成日历控件的input的id设置成calendar,该input就会变成日历控件. < ...

  8. 青瓷引擎之纯JavaScript打造HTML5游戏第二弹——《跳跃的方块》Part 10(排行榜界面&界面管理)

    继上一次介绍了<神奇的六边形>的完整游戏开发流程后(可点击这里查看),这次将为大家介绍另外一款魔性游戏<跳跃的方块>的完整开发流程. (点击图片可进入游戏体验) 因内容太多,为 ...

  9. 纯javascript联动的例子

    有人想要学习下纯javascript联动的一些技巧,我这里就以日期的联动为例,附上一些代码至于复杂的省市区联动,不建议用纯javascript的,而是用ajax的方式,该不在此讨论范围内,想要了解aj ...

随机推荐

  1. Photoshop 更改图片颜色

    程序猿兼职美术的常常没有时间搞太多图片.我们能够一张图片更改主要颜色来到达目的.我知道的主要有2种方法,1是更改色相,2是替换颜色.直接用油漆桶仅仅能在异常简单的图片才干用. 1. 更改色相      ...

  2. MongoDB经常使用命令

    首先我们先安装这个数据库.你能够使用windows或者linux,但推荐使用的是linux,我使用的是ubuntu12.04.在下方的网址中共能够下载,基本都是64位的系统. 假设位linux系统也能 ...

  3. Serialization and deserialization are bottlenecks in parallel and distributed computing, especially in machine learning applications with large objects and large quantities of data.

    Serialization and deserialization are bottlenecks in parallel and distributed computing, especially ...

  4. BZOJ2327: [HNOI2011]勾股定理

    BZOJ2327: [HNOI2011]勾股定理 Description 题解Here! 这是一道神题... 我一开始把题目看错了,我以为是在$n$根木棒中选两个$i,j$满足$gcd(i,j)==1 ...

  5. HTTP协议六种请求方法,get,head,put,delete,post有什么区别

    标准Http协议支持六种请求方法,即: 1.GET 2.POST 3.PUT 4.Delete 5.HEAD 6.Options 但其实我们大部分情况下只用到了GET和POST.如果想设计一个符合RE ...

  6. 20170225-第三件事:FR0002测试

    第三件事:FR0002测试             MATNR WERKS BERID 800000217 I010               问题,上for all entrys…       1 ...

  7. C# delegate Action<T> lambda表达式

    转载以记录:http://blog.csdn.net/educast/article/details/7219854 在使用 Action<T> 委托时,不必显式定义一个封装只有一个参数的 ...

  8. SWT.Shell

    import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class SWT_Shell ...

  9. HDU 3714/UVA1476 Error Curves

    Error Curves Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  10. YTU 1439: 2.4.5 Fractions to Decimals 分数化小数

    1439: 2.4.5 Fractions to Decimals 分数化小数 时间限制: 1 Sec  内存限制: 64 MB 提交: 194  解决: 13 题目描述 写一个程序,输入一个形如N/ ...