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

xiaoxiao2021-02-28  94

单纯的手写滚动条dataTables表格插件下的滚动条 HTML部分代码 js部分代码

单纯的手写滚动条

这里调试过,没问题,可以直接复制了浏览器调试查看效果 大致思路:设置包裹内容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表格插件下的滚动条

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

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>  加载中</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);
转载请注明原文地址: https://www.6miu.com/read-35431.html

最新回复(0)