手写滚动条,以及dataTables表格插件下的手写滚动条

单纯的手写滚动条

这里调试过,没问题,可以直接复制了浏览器调试查看效果
大致思路:设置包裹内容div的容器div的overflow-y为hidden;调整内容div的top来滚动显示内容div的不同位置内容。检测鼠标滚动事件,设置容器div的max-height来设定每次最多显示多少px的内容,设置每次滚动滚多少px,也可通过拖动手写滚动条来快速访问;
手写的滚动条是容器div的第一个子div,贴容器div最右边,包括滚动条和内部滚轮,平时不显示,滚动或者鼠标移上去才显示,显示后又渐渐消失,保证不影响视觉效果。
滚动时,当鼠标在内容div区域时,如果可以滚动,优先滚动内容div,滚动到底或顶后再滚动外部页面。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Scrollbar</title>

    <!--引入jQuery-->
    <script src="http://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
</head>
<body>

<!--
    外容器
    给定了最大高度,设置竖直方向溢出时不显示,设置border以方便查看效果,设置position以配合自定义滚动条的
-->
<div id="wrapper" style="overflow-y: hidden;max-height: 500px;position: relative;border: 1px solid black;">

    <!--
        自定义的滚动条
        设置z-index显示在最顶层,设置初始完全透明
    -->
    <div id="scrollbar" style="box-sizing:border-box;position:absolute;right:0;height:100%;z-index:100;opacity:0;padding:4px;width: 18px;">

        <!--
            自定义滚动条的滚轮
            移动方式为:设置position:relative,通过设置top来上下移动,设置border-radius美化外观
        -->
        <div id="scrollbar_roller" style="position:relative;top: 0px;width:100%;background-color:lightgray;border-radius:5px;"></div>
    </div>

    <!--
        容器包裹的内容
        此处为方便查看效果设置height
    -->
    <div id="content" style="width:100%;height: 2000px;">
    </div>
</div>


<script>

    //当前可视区域高度
    var visibleHeight = $('#wrapper').height();
    //可视区域最大可达到的高度
    var maxVisibleHeight = 500;
    //鼠标滚轮一次滚动对应的高度
    var rollHeight = 200;
    //超出可视区域顶部的部分的高度
    var topHeight = 0;
    //超出可视区域底部的部分的高度
    var elseHeight = 0;

    //向上滚动时触发的函数
    var upScrollFunc = function (e) {

        //获取当前可视区域的高度
        visibleHeight = $('#wrapper').height();

        if (visibleHeight == maxVisibleHeight) {
            //此时当前可视区域高度已达到可允许的最大高度,说明表格的实际高度大于显示高度(暂不考虑等于)
            if ($('#content').height() > visibleHeight) {

                //当滚动条高度发生变化时,或初始化滚动条高度时,设置滚动条滚轮的高度
                $('#scrollbar_roller').css('height', Math.round($('#scrollbar').height() * visibleHeight / $('#content').height()) + 'px');

                if (topHeight == 0) {
                    //topHeight为0,说明此时没发生过向下滚动事件

                    //为table位移做准备
                    $('#content').css({'position': 'relative', 'top': '0px'});

                    //超出可视区域底部的高度=内容高度-当前可视区域高度(可视区域最大可达到的高度)
                    elseHeight = $('#content').height() - visibleHeight;

                    //stop停止自定义滚动条当前的动画,并slow设置滚动条透明度从0到1,完成后在2s内从1到0
                    $('#scrollbar').stop().animate({opacity: "1"}, 'fast', function () {
                        $('#scrollbar').stop().animate({opacity: "0"}, 'slow');
                    });

                    //设置滚动条到顶上
                    $('#scrollbar_roller').animate({'top': '0px'}, 1);

                } else if (topHeight > rollHeight) {
                    //有topHeight,说明之前已经发生过向下滚动事件,
                    //判断:如果滚动的幅度大于一次位移的标准幅度

                    //避免里面滚动条滚动时外面的页面也在滚动
                    e.preventDefault();

                    //topHeight-一次标准位移幅度
                    topHeight -= rollHeight;

                    //内容div向上滚动一次标准位移幅度
                    $('#content').css({'position': 'relative', 'top': '-' + topHeight + 'px'});

                    //底部不可见部分高度增加一次标准位移幅度
                    elseHeight += rollHeight;

                    //滚动条top设为相应比例的位移,显示滚动条并缓缓消失
                    $('#scrollbar').stop().animate({opacity: "1"}, 'fast', function () {
                        $('#scrollbar').stop().animate({opacity: "0"}, 'slow');
                    });
                    $('#scrollbar_roller').animate({'top': Math.round($('#scrollbar').height() * topHeight / $('#content').height()) + 'px'}, 1);

                } else if (topHeight <= rollHeight) {
                    //滚动幅度小于一次位移标准幅度,则说明此时再向上滚动直接滚到顶了

                    //避免里面滚动条滚动时外面的页面也在滚动
                    e.preventDefault();

                    //归零top,topHeight,设置新的elseHeight
                    $('#content').css({'position': 'relative', 'top': '0px'});
                    topHeight = 0;
                    elseHeight = $('#content').height() - visibleHeight;

                    //直接设置滚动条top为0
                    $('#scrollbar').stop().animate({opacity: "1"}, 'fast', function () {
                        $('#scrollbar').stop().animate({opacity: "0"}, 'slow');
                    });
                    $('#scrollbar_roller').animate({'top': '0px'}, 1);

                }

            }
        } else {
            //此时内容div还未填充满容器div,滚动条不显示
            $('#scrollbar').css('height', '0px');
            $('#scrollbar_roller').css({'height': '0px', 'top': '0px'});
        }

    }

    //向下滚动时触发的函数
    var downScrollFunc = function (e) {

        visibleHeight = $('#wrapper').height();

        if (visibleHeight == maxVisibleHeight) {

            if ($('#content').height() > visibleHeight) {

                //当滚动条高度发生变化时,或初始化滚动条高度时,设置滚动条高度
                $('#scrollbar_roller').css('height', Math.round($('#scrollbar').height() * visibleHeight / $('#content').height()) + 'px');

                //如果两者都为0,说明此时页面刚加载
                //初始化elseHeight
                if (elseHeight == 0 && topHeight == 0) {
                    elseHeight = $('#content').height() - visibleHeight;
                }

                if (elseHeight == 0) {
                    //已滚到内容div最底部
                    topHeight = $('#content').height() - visibleHeight;

                    $('#content').css({'position': 'relative', 'top': '-' + topHeight + 'px'});

                    $('#scrollbar').stop().animate({opacity: "1"}, 'fast', function () {
                        $('#scrollbar').stop().animate({opacity: "0"}, 'slow');
                    });
                } else if (elseHeight > rollHeight) {
                    //至少还可以完整的滚一次
                    e.preventDefault();

                    topHeight += rollHeight;
                    $('#content').css({'position': 'relative', 'top': '-' + topHeight + 'px'});
                    elseHeight -= rollHeight;

                    //根据当前相应的位移比例设置滚动条的top,并让滚动条显示后缓缓消失
                    $('#scrollbar').stop().animate({opacity: "1"}, 'fast', function () {
                        $('#scrollbar').stop().animate({opacity: "0"}, 'slow');
                    });
                    $('#scrollbar_roller').animate({'top': Math.round((topHeight / $('#content').height()) * $('#scrollbar').height()) + 'px'}, 1);

                } else if (elseHeight <= rollHeight) {
                    //只能不完整地滚一次滚到底
                    e.preventDefault();

                    //设置elseHeight为0
                    elseHeight = 0;

                    //topHeight直接设置为table整体高度-当前可见部分的高度
                    topHeight = $('#content').height() - visibleHeight;

                    //用新的topHeight设置table的top
                    $('#content').css({'position': 'relative', 'top': '-' + topHeight + 'px'});

                    //设置滚动条top为(滚动条父级div-滚动条高度),并让滚动条显示后缓缓消失
                    $('#scrollbar').stop().animate({opacity: "1"}, 'fast', function () {
                        $('#scrollbar').stop().animate({opacity: "0"}, 'slow');
                    });
                    $('#scrollbar_roller').animate({'top': $('#scrollbar').height() - $('#scrollbar_roller').height() + 'px'}, 1);
                }

            }
        } else {
            $('#scrollbar').css('height', '0px');
            $('#scrollbar_roller').css({'height': '0px', 'top': '0px'});
        }

    }

    //滚动方法
    var scrollFunc = function (e) {

        //浏览器兼容性适配
        e = e || window.event;

        if (e.wheelDelta) { //其他浏览器支持的属性

            if (e.wheelDelta > 0) { //当滑轮向上滚动时
                upScrollFunc(e);
            }
            if (e.wheelDelta < 0) { //当滑轮向下滚动时
                downScrollFunc(e);
            }
        } else if (e.detail) {  //火狐浏览器支持的属性

            if (e.detail< 0) { //当滑轮向上滚动时
                upScrollFunc(e);
            }
            if (e.detail> 0) { //当滑轮向下滚动时
                downScrollFunc(e);
            }
        }
    }

    //绑定滚动方法
    if ($('#content')[0].addEventListener) {
        //非firefox
        $('#content')[0].addEventListener('mousewheel', scrollFunc, false);

        //firefox
        $('#content')[0].addEventListener('DOMMouseScroll', scrollFunc, false);
    }

    //注意,此处content本来是不能加resize的,实际开发中没有发现这个问题,可能是框架自带了吧,
    //于是搜到了这个方法,添加进来后就可以给content这个div加resize事件了
    (function($, h, c) {
        var a = $([]), e = $.resize = $.extend($.resize, {}), i, k = "setTimeout", j = "resize", d = j
            + "-special-event", b = "delay", f = "throttleWindow";
        e[b] = 350;
        e[f] = true;
        $.event.special[j] = {
            setup : function() {
                if (!e[f] && this[k]) {
                    return false
                }
                var l = $(this);
                a = a.add(l);
                $.data(this, d, {
                    w : l.width(),
                    h : l.height()
                });
                if (a.length === 1) {
                    g()
                }
            },
            teardown : function() {
                if (!e[f] && this[k]) {
                    return false
                }
                var l = $(this);
                a = a.not(l);
                l.removeData(d);
                if (!a.length) {
                    clearTimeout(i)
                }
            },
            add : function(l) {
                if (!e[f] && this[k]) {
                    return false
                }
                var n;
                function m(s, o, p) {
                    var q = $(this), r = $.data(this, d);
                    r.w = o !== c ? o : q.width();
                    r.h = p !== c ? p : q.height();
                    n.apply(this, arguments)
                }
                if ($.isFunction(l)) {
                    n = l;
                    return m
                } else {
                    n = l.handler;
                    l.handler = m
                }
            }
        };
        function g() {
            i = h[k](function() {
                a.each(function() {
                    var n = $(this), m = n.width(), l = n.height(), o = $
                        .data(this, d);
                    if (m !== o.w || l !== o.h) {
                        n.trigger(j, [ o.w = m, o.h = l ])
                    }
                });
                g()
            }, e[b])
        }
    })(jQuery, this);

    //内容div的resize事件
    $('#content').resize(function(){

        alert('test');
        //resize发生时,已溢出
        if(visibleHeight == maxVisibleHeight){
            //如果table高度发生变化
            if($('#content').height() !== $('#wrapper').data('#content_height')){
                //计算对应之前比例的新topHeight
                topHeight *= $('#content').height()/$('#wrapper').data('content_height');

                $('#scrollbar_roller').css('height', Math.round($('#scrollbar').height()*visibleHeight/$('#content').height())+'px');
            }
        }else{
            topHeight=0;
            $('#scrollbar').css('height','0px');
            $('#scrollbar_roller').css({'height':'0px','top':'0px'});
        }
        //如果底部出现了空白
        if (topHeight + visibleHeight > $('#content').height()) {
            //滚动条移动到底部
            topHeight = $('#content').height() - visibleHeight;
        }
        elseHeight = $('#content').height() - topHeight - visibleHeight;
        $('#content').css({'position': 'relative', 'top': '-' + topHeight + 'px'});

        //设置当前table高度为新data数据
        $('#wrapper').data('content_height',$('#content').height());

    });


    //-----------------滚动条拖动-----------------
    //记录滚动条区域mousedown事件时鼠标滚轮的top
    var topPlace=0;
    //记录滚动条区域mousedown事件时鼠标的点击处的pageY
    var topPointY=0;

    //鼠标在滚动条范围时,鼠标slow完全不透明
    $('#scrollbar_roller').mouseover(function () {
        $('#scrollbar').stop().animate({opacity:"1"}, 'fast');
    });

    //鼠标移出滚动条范围时,鼠标slow完全透明
    $('#scrollbar_roller').mouseleave(function () {
        $('#scrollbar').stop().animate({opacity:"0"},"slow");
    });

    //滚动条区域mousedown事件
    //按住滚轮时,记录此时的pageY和top
    $('#scrollbar_roller').mousedown(function (event) {
        topPlace=$('#scrollbar_roller').css('top');
        topPlace=parseInt(topPlace.substr(0, topPlace.length-2));
        topPointY=event.pageY;

        //忘了是干嘛的了?阻止事件冒泡?
        return false;
    });

    //滚动条区域mousemove事件,表格区域mousemove事件
    $('#scrollbar_roller').mousemove(function (event) {
        //兼容性设置
        event = event || window.event;

        //神坑,firefox中event.which不点鼠标和点鼠标左键都是1,幸亏还有event.buttons
        if(event.buttons == 1){

            //计算出滚动新的top,move时的pageY-down时的pageY就是位移。
            var newPlace=topPlace+event.pageY-topPointY;
            var ceilLimit=$('#scrollbar').height()-$('#scrollbar_roller').height();

            if(newPlace>0 && newPlace<ceilLimit){
                $('#scrollbar_roller').css('top',newPlace+'px');
                topHeight=newPlace/$('#scrollbar').height()*$('#content').height();
                elseHeight=$('#content').height()-topHeight-maxVisibleHeight;
                $('#content').css({'position':'relative','top':'-'+topHeight+'px'});
            }else if(newPlace<=0){
                $('#scrollbar_roller').css('top','0px');
                topHeight=0;
                elseHeight=$('#content').height()-maxVisibleHeight;
                $('#content').css({'position':'relative','top':'0px'});
            }else if(newPlace>=ceilLimit){
                $('#scrollbar_roller').css('top', ceilLimit+'px');
                topHeight=$('#content').height()-maxVisibleHeight;
                elseHeight=0;
                $('#content').css({'position':'relative','top':'-'+($('#content').height()-maxVisibleHeight)+'px'});
            }

        }
    });

    $('#wrapper').mousemove(function (event) {

        event = event || window.event;

        //如果鼠标移动的时候还按着鼠标左键
        if(event.buttons==1 && topPointY){
            $('#scrollbar').stop().css({'opacity':'1'});
            //滚动条将要位移到的新位置,以top为定义
            var newPlace=topPlace+event.pageY-topPointY;
            //newplace的天花板,最大位移不能超过天花板
            var ceilLimit=$('#scrollbar').height()-$('#scrollbar_roller').height();

            //如果位移后newplace在top取值范围内
            if(newPlace>0 && newPlace<ceilLimit){
                $('#scrollbar_roller').css('top',newPlace+'px');
                topHeight=newPlace/$('#scrollbar').height()*$('#content').height();
                elseHeight=$('#content').height()-topHeight-maxVisibleHeight;
                $('#content').css({'position':'relative','top':'-'+topHeight+'px'});
            }else if(newPlace<=0){  //newplace超出顶部
                $('#scrollbar_roller').css('top','0px');
                topHeight=0;
                elseHeight=$('#content').height()-maxVisibleHeight;
                $('#content').css({'position':'relative','top':'0px'});
            }else if(newPlace>=ceilLimit){  //newplace超出底部
                $('#scrollbar_roller').css('top', ceilLimit+'px');
                topHeight=$('#content').height()-maxVisibleHeight;
                elseHeight=0;
                $('#content').css({'position':'relative','top':'-'+($('#content').height()-maxVisibleHeight)+'px'});
            }
        }
    });

    //页面内mouseup事件
    $('body').mouseup(function () {
        topPlace=0;
        topPointY=0;
        $('#scrollbar').stop().animate({opacity:"0"},"slow");
    });

    //页面内mouseLeave事件
    $('body').mouseleave(function () {
        $('#scrollbar').stop().animate({opacity:"0"},"slow");
    });
</script>
</body>
</html>

dataTables表格插件下的滚动条

  1. 之所以要弄这个手写滚动条,是因为组长觉得,外面页面一个滚动条,里面表格再一个滚动条,不好看。不加滚动条全部显示出来的话,点击分页跳转又不方便,反正没事儿我就试着自己写了个。
  2. 可惜组长最后还是觉得一进来就有水平滚动条不好,不能一眼看到全部数据,哎,那么多列,dataTables缩小页面的时候直接就把多的列hide了,把水平滚动条弄出来方便响应式不好么?不能理解设计思路,现在把表头都压换行了,特丑。
  3. 去掉了框架有关的类和其他的,想用到自己的项目中的话,具体代码需要适当改动
  4. 这个插件也挺坑的,哎,具体看注释吧,以后有时间再写详细点

HTML部分代码:

                <header style="position: relative;">
                    <!--略-->
                </header>

                <div style="position:relative;">

                    <div id="scrollbar" style="box-sizing:content-box;position:absolute;right:0;z-index:100;opacity:0;padding:4px;width: 10px;">
                        <div style="position:relative;top: 0px;width:100%;background-color:lightgray;border-radius:5px;">
                        </div>
                    </div>

                    <div>
                        <table id="example" class="table table-striped table-bordered" width="100%"></table>
                    </div>

                </div>
                <!--这里是加个加载中的提示,要点是遮住整个还没加载数据的空dataTable-->
                <footer style="position:absolute;top:33px;width:100%;height:160px;line-height:100px;background-color:white;text-align: center; font-size: x-large; padding: 30px 0px;z-index:100;">
                    <span><i class="fa fa-refresh fa-spin"></i>&nbsp;&nbsp;加载中</span>
                </footer>

js部分代码:

/*
实际开发中,可能有些部分,框架里有,所以没引用某些文件,或者用了一些框架里的方法和类啥的,这些都可能导致错误
*/

    //dataTables表格实例
    var dataTablesObj = null;
    //获取表格column,这里的重点是要设置width,width之间的比例要接近你的各列数据实际长度的比例
    function getColumns(type) {  //type是实际代码里自定义的,跟滚动条无关
        var columns = [
            {title: "xxx", data: "xxx",width:60},
            {title: "xxx", data: "xxx",width:60},
            {title: "xxx", data: "xxx",width:450},
            {title: "xxx", data: "xxx",width:150},
            {title: "xxx", data: "xxx",width:80}
        ];

        return columns;
    }


    // pagefunction
    var pagefunction = function () {

        //将dataTables的content(未载入数据时content会占据部分空间显示无数据)全部隐藏,显示出foot
        $('[role="content"]').hide();
        $('footer').css('z-index', '100');

        //创建dataTables实例的函数,objid是要添加dataTables的id,url是请求的路径,type跟滚动条无关
        function createDataTables(objid, url, type) {
            //提示信息
            var lang = {
                xxx:'xxx...'
            };

            //如果当前有dataTables,则销毁
            if (dataTablesObj) {
                dataTablesObj.destroy();
            }

            //创建dataTables实例
            dataTables = $('#' + objid).DataTable({
                language: lang, //提示信息
//                stateSave: true, //状态保存,再次加载页面时还原表格状态
                autoWidth: false, //禁用自动调整列宽
                stripeClasses: ["odd", "even"], //为奇偶行加上样式,兼容不支持CSS伪类的场合
                processing: true, //隐藏加载提示,自行处理
                serverSide: true, //启用服务器端分页——————启用还是不启用还有渲染上的差别,遇到了要自己调整代码来保证显示显示效果
//                searching: false, //禁用原生搜索
                orderMulti: false, //启用多列排序
                order: [], //取消默认排序查询,否则复选框一列会出现小箭头
                deferRender: true, //延迟渲染可以提高Datatables的加载速度
                lengthMenu: [
                    [10, 25, 50, 100, 300],
                    [10, 25, 50, 100, 300]
                ], //每页多少项,第一个数组是表示的值,第二个数组用来显示
                renderer: "bootstrap", //渲染样式:Bootstrap和jquery-ui
                pagingType: "simple_numbers", //分页样式:simple,simple_numbers,full,full_numbers
//                scrollY: 300, //表格的固定高
//                scrollCollapse: true, //开启滚动条
                scrollX: true,  //设置水平滚动,实际上有了这个,才会有dataTables_scrollHead和body两个类,才好操作
                pageLength: 10, //首次加载的数据条数
                columns: getColumns(type),
                sDom: "<'dt-toolbar'<'col-xs-12 col-sm-8 hidden-xs'><'col-xs-12 col-sm-4  text-right hidden-xs'i><'toolbar'>>" +
                "t" +
                "<'dt-toolbar-footer'<'col-xs-12 col-sm-2  hidden-xs'l><'col-xs-12  col-sm-10'p>>", //各个dataTables的部件的分布位置

                ajax: function(data, callback, settings) {}   //请求数据部分,我直接删完了

            });

//-------------自定义滚动条部分--------------------------
            //获取当前浏览器自带滚动条的宽度
            function getScrollWidth() {
                var noScroll, scroll, Div = document.createElement("div");
                Div.style.cssText = "position:absolute; top:-1000px; width:100px; height:100px; overflow:hidden;";
                noScroll = document.body.appendChild(Div).clientWidth;
                Div.style.overflowY = "scroll";
                scroll = Div.clientWidth;
                document.body.removeChild(Div);
                return noScroll-scroll;
            }

            //表格可视区域高度
            var tableVisibleHeight=$('.dataTables_scrollBody').height();
            //表格可视区域高度
            var maxTableVisibleHeight=500;
            //一次滚动幅度对应的高度
            var rollHeight=200;
            //表格顶部已移动到显示区域外的部分
            var topHeight=0;
            //表格底部还未显示出的部分的高度
            var elseHeight=0;

            //向上滚动时触发的函数
            var upScrollFunc=function (e) {

                //如果table的宽度小于包裹它的div的header的宽度,则此时不会出现水平滚动条。
                if($('.dataTables_scrollHead table').width()<=$($('header')[1]).width()){
                    maxTableVisibleHeight=500;
                    tableVisibleHeight=$('.dataTables_scrollBody').height();

                    if(tableVisibleHeight==maxTableVisibleHeight){
                        //如果表格的实际高度大于显示高度
                        if($('#example').height()>tableVisibleHeight){

                            //有水平滚动条,设置scrollbar高度减去水平滚动条width
                            $('#scrollbar').css('height',tableVisibleHeight-8+'px');

                            //当滚动条高度发生变化时,或初始化滚动条高度时,设置滚动条高度
                            $('#scrollbar').children().css('height', Math.round($('#scrollbar').height()*tableVisibleHeight/$('#example').height())+'px');

                            if(topHeight==0){   //topHeight为0,说明此时没发生过向下滚动事件
                                //为table位移做准备
                                $('#example').css({'position':'relative','top':'0px'});

                                elseHeight=$('#example').height()-tableVisibleHeight;

                                console.log(elseHeight);
                                //stop停止自定义滚动条当前的动画,并slow设置滚动条透明度从0到1,完成后在2s内从1到0
                                $('#scrollbar').stop().animate({opacity:"1"}, 'fast',function(){
                                    $('#scrollbar').stop().animate({opacity:"0"},'slow');
                                });

                                //设置滚动条到顶上
                                $('#scrollbar').children().animate({'top':'0px'},1);

                            }else if(topHeight>rollHeight){   //之前已经发生过向下滚动事件,如果滚动的幅度大于一次位移的标准幅度

                                //避免里面滚动条滚动时外面的页面也在滚动
                                e.preventDefault();

                                //topHeight-一次标准位移幅度
                                topHeight-=rollHeight;

                                //相当于top比之前+了一次标准位移幅度
                                $('#example').css({'position':'relative','top':'-'+topHeight+'px'});

                                //不可见部分高度增加一次标准位移幅度
                                elseHeight+=rollHeight;

                                //滚动条top设为相应比例的位移,显示滚动条并缓缓消失
                                $('#scrollbar').stop().animate({opacity:"1"}, 'fast',function(){
                                    $('#scrollbar').stop().animate({opacity:"0"},'slow');
                                });
                                $('#scrollbar').children().animate({'top':Math.round($('#scrollbar').height()*topHeight/$('#example').height())+'px'},1);

                            }else if(topHeight<=rollHeight){  //滚动幅度小于一次位移标准幅度,则直接归零top,topHeight,设置新的elseHeight

                                //避免里面滚动条滚动时外面的页面也在滚动
                                e.preventDefault();

                                elseHeight=$('#example').height()-tableVisibleHeight;
                                $('#example').css({'position':'relative','top':'0px'});
                                topHeight=0;

                                //直接设置滚动条top为0
                                $('#scrollbar').stop().animate({opacity:"1"}, 'fast',function(){
                                    $('#scrollbar').stop().animate({opacity:"0"},'slow');
                                });
                                $('#scrollbar').children().animate({'top':'0px'},1);

                            }

                        }
                    }else{
                        $('#scrollbar').css('height','0px');
                        $('#scrollbar').children().css({'height':'0px','top':'0px'});
                    }

                }else if($('.dataTables_scrollHead table').width()>$($('header')[1]).width()){
                    //此时table已触发最小宽度设置,出现了水平滚动条,于是将滚动幅度maxTableVisibleHeight设为table外容器高度-水平滚动条width
                    maxTableVisibleHeight=500-getScrollWidth();
                    tableVisibleHeight=$('.dataTables_scrollBody').height()-getScrollWidth();

                    if(tableVisibleHeight==maxTableVisibleHeight) {
                        if($('#example').height()>tableVisibleHeight){

                            //有水平滚动条,设置scrollbar高度减去水平滚动条width
                            $('#scrollbar').css('height',tableVisibleHeight-8+'px');

                            $('#scrollbar').children().css('height', Math.round($('#scrollbar').height()*tableVisibleHeight/$('#example').height())+'px');

                            if(topHeight==0){
                                $('#example').css({'position':'relative','top':'0px'});

                                elseHeight=$('#example').height()-tableVisibleHeight;

                                console.log(elseHeight);

                                $('#scrollbar').stop().animate({opacity:"1"}, 'fast',function(){
                                    $('#scrollbar').stop().animate({opacity:"0"},'slow');
                                });
                                $('#scrollbar').children().animate({'top':'0px'},1);

                            }else if(topHeight>rollHeight){
                                e.preventDefault();

                                topHeight-=rollHeight;
                                $('#example').css({'position':'relative','top':'-'+topHeight+'px'});
                                elseHeight+=rollHeight;

                                $('#scrollbar').stop().animate({opacity:"1"}, 'fast',function(){
                                    $('#scrollbar').stop().animate({opacity:"0"},'slow');
                                });
                                $('#scrollbar').children().animate({'top':Math.round((topHeight/$('#example').height())*$('#scrollbar').height())+'px'},1);

                            }else if(topHeight<=rollHeight){
                                e.preventDefault();

                                elseHeight=$('#example').height()-tableVisibleHeight;
                                $('#example').css({'position':'relative','top':'0px'});
                                topHeight=0;

                                $('#scrollbar').stop().animate({opacity:"1"}, 'fast',function(){
                                    $('#scrollbar').stop().animate({opacity:"0"},'slow');
                                });
                                $('#scrollbar').children().animate({'top':'0px'},1);
                            }

                        }
                    }else{
                        $('#scrollbar').css('height','0px');
                        $('#scrollbar').children().css({'height':'0px','top':'0px'});
                    }

                }
            }

            //向下滚动时触发的函数
            var downScrollFunc=function (e) {

                if($('.dataTables_scrollHead table').width()<=$($('header')[1]).width()){
                    maxTableVisibleHeight=500;
                    tableVisibleHeight=$('.dataTables_scrollBody').height();

                    if(tableVisibleHeight==maxTableVisibleHeight){
                        //如果表格的实际高度大于可视区域高度
                        if($('#example').height()>tableVisibleHeight){

                            $('#scrollbar').css('height',tableVisibleHeight - 8 +'px');
                            //当滚动条高度发生变化时,或初始化滚动条高度时,设置滚动条高度
                            if($('#scrollbar').children().height()!==Math.round($('#scrollbar').height()*tableVisibleHeight/$('#example').height())){
                                $('#scrollbar').children().css('height', Math.round($('#scrollbar').height()*tableVisibleHeight/$('#example').height())+'px');
                            }

                            //初始化elseHeight,获取表格不可见部分的高度
                            if(elseHeight==0 && topHeight ==0){
                                elseHeight=$('#example').height()-tableVisibleHeight;
                            }

                            if (elseHeight == 0){
                                topHeight=$('#example').height()-tableVisibleHeight;

                                $('#example').css({'position':'relative','top':'-'+topHeight+'px'});

                                $('#scrollbar').stop().animate({opacity:"1"}, 'fast',function(){
                                    $('#scrollbar').stop().animate({opacity:"0"},'slow');
                                });
                            }else if(elseHeight>rollHeight){
                                e.preventDefault();

                                topHeight+=rollHeight;
                                $('#example').css({'position':'relative','top':'-'+topHeight+'px'});
                                elseHeight-=rollHeight;

                                //根据当前相应的位移比例设置滚动条的top,并让滚动条显示后缓缓消失
                                $('#scrollbar').stop().animate({opacity:"1"}, 'fast',function(){
                                    $('#scrollbar').stop().animate({opacity:"0"},'slow');
                                });
                                $('#scrollbar').children().animate({'top':Math.round((topHeight/$('#example').height())*$('#scrollbar').height())+'px'},1);

                            }else if(elseHeight<=rollHeight){ //不可见部分高度小于一次标准位移幅度

                                e.preventDefault();

                                //设置elseHeight为0
                                elseHeight=0;

                                //topHeight直接设置为table整体高度-当前可见部分的高度
                                topHeight=$('#example').height()-tableVisibleHeight;

                                //用新的topHeight设置table的top
                                $('#example').css({'position':'relative','top':'-'+topHeight+'px'});

                                //设置滚动条top为(滚动条父级div-滚动条高度),并让滚动条显示后缓缓消失
                                $('#scrollbar').stop().animate({opacity:"1"}, 'fast',function(){
                                    $('#scrollbar').stop().animate({opacity:"0"},'slow');
                                });
                                $('#scrollbar').children().animate({'top':$('#scrollbar').height()-$('#scrollbar').children().height()+'px'},1);
                            }

                        }
                    }else{
                        $('#scrollbar').css('height','0px');
                        $('#scrollbar').children().css({'height':'0px','top':'0px'});
                    }

                }else if($('.dataTables_scrollHead table').width()>$($('header')[1]).width()){
                    //此时table已触发最小宽度设置,出现了水平滚动条,于是将滚动幅度maxTableVisibleHeight设为table外容器高度-水平滚动条width
                    maxTableVisibleHeight=500-getScrollWidth();
                    tableVisibleHeight=$('.dataTables_scrollBody').height()-getScrollWidth();

                    if(tableVisibleHeight==maxTableVisibleHeight) {
                        if ($('#example').height() > tableVisibleHeight) {

                            $('#scrollbar').css('height', tableVisibleHeight- 8 + 'px');
                            //当滚动条高度发生变化时,或初始化滚动条高度时,设置滚动条高度
                            $('#scrollbar').children().css('height', Math.round($('#scrollbar').height() * tableVisibleHeight / $('#example').height()) + 'px');


                            if (elseHeight == 0 && topHeight == 0) {
                                elseHeight = $('#example').height() - tableVisibleHeight;

                            }

                            if (elseHeight == 0) {
                                topHeight = $('#example').height() - tableVisibleHeight;

                                $('#example').css({'position': 'relative', 'top': '-' + topHeight + 'px'});

                                $('#scrollbar').stop().animate({opacity:"1"}, 'fast',function(){
                                    $('#scrollbar').stop().animate({opacity:"0"},'slow');
                                });
                            } else if (elseHeight > rollHeight) {
                                e.preventDefault();

                                topHeight += rollHeight;
                                $('#example').css({'position': 'relative', 'top': '-' + topHeight + 'px'});
                                elseHeight -= rollHeight;

                                $('#scrollbar').stop().animate({opacity: "1"}, function () {
                                    $('#scrollbar').stop().animate({opacity: "0"}, 'slow');
                                });
                                $('#scrollbar').children().animate({'top': Math.round((topHeight / $('#example').height()) * $('#scrollbar').height()) + 'px'}, 1);

                            } else if (elseHeight <= rollHeight) {
                                e.preventDefault();

                                //设置elseHeight为0
                                elseHeight = 0;

                                topHeight = $('#example').height() - tableVisibleHeight;

                                $('#example').css({'position': 'relative', 'top': '-' + topHeight + 'px'});

                                $('#scrollbar').stop().animate({opacity: "1"}, function () {
                                    $('#scrollbar').stop().animate({opacity: "0"}, 'slow');
                                });
                                $('#scrollbar').children().animate({'top': $('#scrollbar').height() - $('#scrollbar').children().height() + 'px'}, 1);
                            }
                        }
                    }else{
                        $('#scrollbar').css('height','0px');
                        $('#scrollbar').children().css({'height':'0px','top':'0px'});
                    }

                }
            }

            //滚动方法
            var scrollFunc = function (e) {

                //浏览器兼容性适配
                e = e || window.event;

                if (e.wheelDelta) { //其他浏览器支持的属性

                    if (e.wheelDelta > 0) { //当滑轮向上滚动时
                        upScrollFunc(e);
                    }
                    if (e.wheelDelta < 0) { //当滑轮向下滚动时
                        downScrollFunc(e);
                    }
                } else if (e.detail) {  //火狐浏览器支持的属性

                    if (e.detail< 0) { //当滑轮向上滚动时
                        upScrollFunc(e);
                    }
                    if (e.detail> 0) { //当滑轮向下滚动时
                        downScrollFunc(e);
                    }
                }
            }

            //绑定滚动方法
            if ($('#example')[0].addEventListener) {
                //非firefox
                $('#example')[0].addEventListener('mousewheel', scrollFunc, false);

                //firefox
                $('#example')[0].addEventListener('DOMMouseScroll', scrollFunc, false);
            }

            //表格resize事件
            $('#example').resize(function(){
                //如果不settimeout,resize后(首次)可能会出现滚动条错位的现象,原因是取得th的高不对
                setTimeout(function () {
                    $('#scrollbar').css('top',$('.dt-toolbar').outerHeight()+$('.dataTables_scrollHead').outerHeight()+'px');
                },10);

                if($('.dataTables_scrollHead table').width()>$($('header')[1]).width()) {
                    maxTableVisibleHeight = 500 - getScrollWidth();
                    tableVisibleHeight = $('.dataTables_scrollBody').height() - getScrollWidth();
                }else{
                    maxTableVisibleHeight = 500;
                    tableVisibleHeight = $('.dataTables_scrollBody').height();
                }

                if(tableVisibleHeight == maxTableVisibleHeight){
                    //如果table高度发生变化
                    if($('#example').height() !== $('.dataTables_scrollBody').data('#example_height')){
                        //计算对应之前比例的新topHeight
                        topHeight *= $('#example').height()/$('.dataTables_scrollBody').data('#example_height');

                        $('#scrollbar').css('height',tableVisibleHeight-8+'px');

                        $('#scrollbar').children().css('height', Math.round($('#scrollbar').height()*tableVisibleHeight/$('#example').height())+'px');
                    }
                }else{
                    topHeight=0;
                    $('#scrollbar').css('height','0px');
                    $('#scrollbar').children().css({'height':'0px','top':'0px'});
                }
                //如果底部出现了空白
                if (topHeight + tableVisibleHeight > $('#example').height()) {
                    //滚动条移动到底部
                    topHeight = $('#example').height() - tableVisibleHeight;
                }
                elseHeight = $('#example').height() - topHeight - tableVisibleHeight;
                $('#example').css({'position': 'relative', 'top': '-' + topHeight + 'px'});

                //设置当前table高度为新data数据
                $('.dataTables_scrollBody').data('#example_height',$('#example').height());


            });


//-----------------滚动条拖动-----------------
            //记录滚动条区域mousedown事件时鼠标滚轮的top
            var topPlace=0;
            //记录滚动条区域mousedown事件时鼠标的点击处的pageY
            var topPointY=0;

            //鼠标在滚动条范围时,鼠标slow完全不透明
            $('#scrollbar').children().mouseover(function () {
                $('#scrollbar').stop().animate({opacity:"1"}, 'fast');
            });

            //鼠标移出滚动条范围时,鼠标slow完全透明
            $('#scrollbar').children().mouseleave(function () {
                $('#scrollbar').stop().animate({opacity:"0"},"slow");
            });

            //滚动条区域mousedown事件
            $('#scrollbar').children().mousedown(function (event) {
                topPlace=$('#scrollbar').children().css('top');
                topPlace=parseInt(topPlace.substr(0, topPlace.length-2));
                topPointY=event.pageY;
                return false;
            });

            //滚动条区域mousemove事件,表格区域mousemove事件
            $('#scrollbar').children().mousemove(function (event) {
                event = event || window.event;

                //神坑,firefox中event.which不点鼠标和点鼠标左键都是1,幸亏还有event.buttons
                if(event.buttons == 1){

                    var newPlace=topPlace+event.pageY-topPointY;
                    var ceilLimit=$('#scrollbar').height()-$('#scrollbar').children().height();

                    if(newPlace>0 && newPlace<ceilLimit){
                        $('#scrollbar').children().css('top',newPlace+'px');
                        topHeight=newPlace/$('#scrollbar').height()*$('#example').height();
                        elseHeight=$('#example').height()-topHeight-maxTableVisibleHeight;
                        $('#example').css({'position':'relative','top':'-'+topHeight+'px'});
                    }else if(newPlace<=0){
                        $('#scrollbar').children().css('top','0px');
                        topHeight=0;
                        elseHeight=$('#example').height()-maxTableVisibleHeight;
                        $('#example').css({'position':'relative','top':'0px'});
                    }else if(newPlace>=ceilLimit){
                        $('#scrollbar').children().css('top', ceilLimit+'px');
                        topHeight=$('#example').height()-maxTableVisibleHeight;
                        elseHeight=0;
                        $('#example').css({'position':'relative','top':'-'+($('#example').height()-maxTableVisibleHeight)+'px'});
                    }

                }
            });

            $('.dataTables_scrollBody').mousemove(function (event) {

                event = event || window.event;

                //如果鼠标移动的时候还按着鼠标左键
                if(event.buttons==1 && topPointY){
                    $('#scrollbar').stop().css({'opacity':'1'});
                    //滚动条将要位移到的新位置,以top为定义
                    var newPlace=topPlace+event.pageY-topPointY;
                    //newplace的天花板,最大位移不能超过天花板
                    var ceilLimit=$('#scrollbar').height()-$('#scrollbar').children().height();

                    //如果位移后newplace在top取值范围内
                    if(newPlace>0 && newPlace<ceilLimit){
                        $('#scrollbar').children().css('top',newPlace+'px');
                        topHeight=newPlace/$('#scrollbar').height()*$('#example').height();
                        elseHeight=$('#example').height()-topHeight-maxTableVisibleHeight;
                        $('#example').css({'position':'relative','top':'-'+topHeight+'px'});
                    }else if(newPlace<=0){  //newplace超出顶部
                        $('#scrollbar').children().css('top','0px');
                        topHeight=0;
                        elseHeight=$('#example').height()-maxTableVisibleHeight;
                        $('#example').css({'position':'relative','top':'0px'});
                    }else if(newPlace>=ceilLimit){  //newplace超出底部
                        $('#scrollbar').children().css('top', ceilLimit+'px');
                        topHeight=$('#example').height()-maxTableVisibleHeight;
                        elseHeight=0;
                        $('#example').css({'position':'relative','top':'-'+($('#example').height()-maxTableVisibleHeight)+'px'});
                    }
                }
            });

            //页面内mouseup事件
            $('body').mouseup(function () {
                topPlace=0;
                topPointY=0;
                $('#scrollbar').stop().animate({opacity:"0"},"slow");
            });

            //页面内mouseLeave事件
            $('body').mouseleave(function () {
                $('#scrollbar').stop().animate({opacity:"0"},"slow");
            });

//--------------滚动条拖动部分完---------------------

            //dataTables的draw事件,重绘时触发,包括初次载入和页面改变等情况
            dataTables.on('draw.dt',function () {

                //初始化时设置由scorllX:ture产生的dataTables_scrollBody类的css
                // 必须要在这里设,不然可能让该类的内容溢出了再设置回500px,这之间就会导致某些判断错误
                $('.dataTables_scrollBody').css({
                    'max-height': '500px',
                    'overflow-y': 'hidden'
                });

                //设置scrollbar的顶部top,以免和dataTables的表头等部分重叠
                $('#scrollbar').css('top',$('.dt-toolbar').outerHeight()+$('th').outerHeight()+'px');

                //给所有td加上折行样式
                $('td').css({'word-break':'break-all','word-wrap':'break-word'});

                //当“无数据”时,实际上dataTables是设置了一个横跨所有col的td,有时候会显示出错,所以这里再设置一下
                if ($('td').length == 1) {
                    $('td').attr('colspan', $('.dataTables_scrollHead table').find('th').length);
                }

                //datatables的columns定义的宽度数组,在getcolumns里面写的有
                var len=['xxx','xxx','xxx','...'];

                //dataTables的表格的最小宽度
                var table_min_length=0;
                for(i=0;i<len.length;i++){
                    //累加给最小宽度当前column的设定宽度和左右padding合计27
                    table_min_length+=len[i]+27;
                }
                //column之间的border
                table_min_length+=len.length-1;

                //这个函数真正反映了我改的时候遇到了多少dataTables的坑。。。
                function changeTableWidth() {

                    //检测widget的宽度,根据此宽度来改变table的宽度————widget是框架里的,自己酌情改,实际上是检测dataTables外围容器div的宽度
                    var headerWidth = $($('header')[1]).width();

                    //如果当前容器div的宽度小于设定的dataTables表格的最小宽度
                    if (headerWidth <= table_min_length) {
                        //把表头table和表内容table都设为设定最小宽度。
                        $('.dataTables_scrollHead table').width(table_min_length);
                        $('.dataTables_scrollBody table').width(table_min_length);
                    } else {
                        //否则跟随容器宽度变化
                        $('.dataTables_scrollHead table').width(headerWidth);
                        $('.dataTables_scrollBody table').width(headerWidth);
                    }

                    //当表格不为空时,这里很坑,可以试着改动部分看会出现啥结果
                    //最终效果是——大部分分页的表格都会显示的很好,只有最后的几个分页的表格的col会发生微小的宽度变化,不影响使用
                    if ($('td').length > 1) {
                        //当第一行第一列的宽度和第一列表头的宽度对不上时(7是th和td的padding的差),或者是当第一行第一列的宽度小于设定的最小宽度(即前面的差+设置给表头的len[0])时
                        if ($($('td')[0]).width() - 7 !== $($('th')[0]).width() || $($('td')[0]).width() < 67) {
                            //获取此时第一行第一列单元格的width
                            var diff = $($('td')[0]).width();
                            //最后再给单元格一个机会改回设定的width
                            var bodyArr = $('.dataTables_scrollBody table').find('tr');
                            for (var i = 1; i < bodyArr.length; i++) {
                                for (var j = 0; j < len.length; j++) {
                                    $($(bodyArr[i]).find('td')[j]).css('width', len[j] + 7);
                                }
                            }

                            //如果小于设置的最小width,或者小于等于之前它的width
                            if ($($('td')[0]).width() < 67 || $($('td')[0]).width() <= diff) {
                                //定义一个空数组,用来记录此时第一行的各个单元格的宽度。
                                var len2 = [];
                                for (var i = 0; i < len.length; i++) {
                                    len2.push($($('td')[i]).width());
                                }
                                //console.log(len2);
                                //把表头各个单元格的宽度设置为第一行的相应宽度
                                var headArr = $('.dataTables_scrollHead table').find('th');
                                for (var i = 0; i < headArr.length; i++) {
                                    $(headArr[i]).css('width', len2[i] - 7);
                                }
                            }

                        }
                    }

                }

                //先执行一遍
                changeTableWidth();

                //显示表格,隐藏加载中提示
                $('footer').css('z-index', '-1');
                $('[role="content"]').show();

                //当外围容器div触发resize事件时,调用之前定义的方法。
                $('.widget-body').resize(changeTableWidth);

                //定义表格的单元格应有的理想宽度————这里不是写错了,实际上就是要在这里再写一遍,坑
                var headArr = $('.dataTables_scrollHead table').find('th');
                for (var i = 0; i < headArr.length; i++) {
                    $(headArr[i]).css('width', len[i]);
                }
                var bodyArr = $('.dataTables_scrollBody table').find('tr');
                if ($('td').length > 1) {
                    for (var i = 1; i < bodyArr.length; i++) {
                        for (var j = 0; j < len.length; j++) {
                            $($(bodyArr[i]).find('td')[j]).css('width', len[j] + 7);
                        }
                    }
                } else if ($('td').length == 1) {
                    $('td').attr('colspan', len.length);
                }


                //重绘时清空height数据,调整滚动条和table的top都到顶部
                topHeight=0;
                elseHeight=0;
                $('#scrollbar').children().css('top','0px');
                $('#example').css({'position':'relative','top':'0px'});

                if($('.dataTables_scrollHead table').width()<=$($('header')[1]).width()) {  //如果table的宽度小于包裹它的div的header的宽度,则此时不会出现水平滚动条。
                    maxTableVisibleHeight = 500;
                    tableVisibleHeight = $('.dataTables_scrollBody').height();
                }else{  //出现水平滚动条,减去相应的滚动条width
                    maxTableVisibleHeight = 500-getScrollWidth();

                    tableVisibleHeight = $('.dataTables_scrollBody').height()-getScrollWidth();

                }

                if(tableVisibleHeight<maxTableVisibleHeight){   //如果表格高度还达不到最大高度
                    $('#scrollbar').css('height','0px');
                    $('#scrollbar').children().css({'height':'0px','top':'0px'});
                }else{
                    $('#scrollbar').css('height',tableVisibleHeight - 8 +'px');

                    //滚动条的滚轮的大小是根据当前可视区域相对于整个table表的比例乘以整个滚动条的高度得到的
                    $('#scrollbar').children().css('height', Math.round($('#scrollbar').height()*tableVisibleHeight/$('#example').height())+'px');

                }

                //在每次重绘时时记录table的实际高度
                $('.dataTables_scrollBody').data('#example_height',$('#example').height());

            });

            //返回实例
            return dataTables;
        }

        //返回实例
        dataTablesObj = createDataTables('xxx','xxx','xxx');

    };

    // 嵌套load一堆js后触发pagefunction
    loadScript("../static/framework/js/plugin/datatable-responsive/datatables.responsive.min.js", pagefunction);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值