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. socket 网络编程高速入门(一)教你编写基于UDP/TCP的服务(client)通信

    由于UNIX和Win的socket大同小异,为了方便和大众化,这里先介绍Winsock编程. socket 网络编程的难点在入门的时候就是对基本函数的了解和使用,由于这些函数的结构往往比較复杂,參数大 ...

  2. [WF4.0 实战] 事件驱动应用

    看到题目或许非常多人都会疑问,为什么要使用事件监听呢? 眼下的认识: 1,使用事件监听能够将工作流的结点返回值返回到client 2,能够实现等待与重新启动,相当于之前的WaitActivity创建B ...

  3. javascript参数arguments对象

    ECMAScript函数的参数与大多树其他语言中函数的参数有所不同.ECMAScript函数不介意传递进来多少个参数,也不在乎传进来参数是什么类型.函数体是通过arguments对象来访问参数数组.a ...

  4. openwrt gstreamer实例学习笔记(二.gstreamer 的 Element)

    对程序员来说,GStreamer 中最重要的一个概念就是 GstElement 对象.该对象是构建一个媒体管道的基本块.所有上层(high-level)部件都源自GstElement对象.任何一个解码 ...

  5. Arcgis Engine(ae)接口详解(8):临时元素(element)

    //主地图的地图(map)对象 IMap map = null; IActiveView activeView = null; //IGraphicsContainer用于操作临时元素,可以通过map ...

  6. Monkey测试的参数

    一.Monkey测试简介 Monkey测试是Android平台自动化测试的一种手段,通过Monkey程序模拟用户触摸屏幕.滑动Trackball.按键等操作来对设备上的程序进行压 力测试,检测程序多久 ...

  7. VC++中全局变量的问题(转)

    全局变量一般这样定义:1.在一类的.cpp中定义 int myInt;然后再在要用到的地方的.cpp里extern int myInt:这样就可以用了. 2.在stdafx.cpp中加入:int my ...

  8. 回溯法——求解N皇后问题

    问题描写叙述 八皇后问题是十九世纪著名数学家高斯于1850年提出的.问题是:在8*8的棋盘上摆放8个皇后.使其不能互相攻击,即随意的两个皇后不能处在允许行.同一列,或允许斜线上. 能够把八皇后问题拓展 ...

  9. apt仓库以及apt-get分析

    1 debian repository 参考:https://wiki.debian.org/DebianRepository 1.1 版本代号 sid,still in development,该版 ...

  10. __sizeof__()

    https://bugs.python.org/issue2898 https://bugs.python.org/file10353/footprint.patch Index: Python/sy ...