bootstrap table 固定 表头 冻结 窗格 固定首行 冻结首行 fixed 对齐 分享

bqldragon 1月前 188

  • 当表格数据特别多行超过屏幕后,我们需要冻结表头,也叫做冻结窗格,也叫做首行固定等!
  • 思路:采用jQuery,复制一份源表头,然后fixed,通过判断scroll滑动的事件动态修改position的值,以及表头的显示与隐藏。
  • 代码:添加位置要注意
table.on('load-success.bs.table', function (e, data) {//首行冻结.....
//首行冻结结束
});
  • 需要固定首行的表格,我们在控制器对应的js中,当表格数据加载完成这个事件中加入代码
                //首行冻结
                //点击分页时候内容改变了,表格宽度就有变化,我们需要动态的修改固定表头的宽度,所以开始的时候删除上次添加的表头重新生成
                if($("#shelter").length > 0) { 
                    //元素存在时执行的代码
                    $('#shelter').remove();
                }

                var sourceTable = $("#table");//源表格的ID
                var sourceTableHead = $("#table thead");//需要冻结的表头部分
                var headHeight = sourceTableHead.height();//冻结部分的高度
                var sourceTableWidth = sourceTable.outerWidth(); //源表格宽度
                var testDiv = $(".fixed-table-body"); //测试内容宽度
                var wrapDiv = $(".fixed-table-container"); //滚动条外部ID,测量DIV与头部的高度
                var tempTop = wrapDiv.offset().top - $(window).scrollTop(); //测量DIV与网页的高度
                //从源表格copy一个份表头和其中元素插入
                //插入一个表格用来存放我们要固定的表头
                $('#table').append('<div id="shelter" style="margin-left:30px;box-shadow: 0px 0px 4px #888888;"><div id="fixed_table_wrap"><table id="fixed_table" class="table table-hover"></table></div></div>');

                var fixTopDiv = $("#shelter");
                fixTopDiv.hide();
                //首行固定,首行先左侧滑动
                fixTopDiv.css({
                    'height':headHeight,
                    'position':'fixed',
                    'top':tempTop+"px",
                    'left':'0',
                    'width':testDiv.width()+"px",
                    'overflow':'hidden'
                });
                //设置fixed表头的宽度与源一致
                $("#fixed_table_wrap,#fixed_table").css({'width':sourceTableWidth+"px"});
                //设置每一个th元素与源th宽度一致达到对齐的效果,并且每次点击分页按钮时候都会重新设置
                var targetHead = sourceTableHead.clone().attr('id','fix_head');
                //这个加入位置比较偷懒的继承了bootstrap-table的结构css样式,使得冻结的表头与源表样式一致
                targetHead.appendTo('#fixed_table');
                $("#table thead tr th").each(function(index,value){

                    var tempWidth =  $(value).outerWidth();
                    var tempHeight = $(value).outerHeight();
                    $("#fixed_table th").eq(index).css({'width':tempWidth+"px",'height':tempHeight+"px"});
                });


                //div内容scroll
                wrapDiv=$(".fixed-table-body");
                wrapDiv.scroll(function(){
                    //与源表格同步左右滑动
                    var sl=-Math.max(wrapDiv.scrollLeft(),$('document').scrollLeft());
                    if(isNaN(sl)){
                        sl = - wrapDiv.scrollLeft();
                    }
                    fixTopDiv.css("left",sl+'px');
                    var scroll_top = wrapDiv.scrollTop() - headHeight + $(window).scrollTop();
                    tempTop = wrapDiv.offset().top - $(window).scrollTop();
                    if(tempTop <= 0){
                        tempTop = 0;
                    }
                    var baseWidth = testDiv.width() + wrapDiv.scrollLeft();
                    //控制隐藏或显示
                    if (scroll_top >= 0) {
                        fixTopDiv.css({'top':tempTop +"px",'width':baseWidth+"px"});
                        if(!fixTopDiv.is(':visible')){
                            fixTopDiv.show();
                        }
                    }else {
                        if(fixTopDiv.is(':visible')){
                            fixTopDiv.hide();
                        }

                    }
                });

                //浏览器scroll
                $(window).on('scroll',function(){
                    tempTop = wrapDiv.offset().top - $(window).scrollTop();
                    var scroll_top = wrapDiv.scrollTop() - headHeight + $(window).scrollTop();
                    var baseWidth = testDiv.width() + wrapDiv.scrollLeft();
                    if(tempTop <= 0){
                        tempTop = 0;
                    }
                    fixTopDiv.css({'top':tempTop +"px",'width':baseWidth+"px"});
                    //控制显示或输出
                    if (scroll_top >= 0) {
                        if(!fixTopDiv.is(':visible')){
                            fixTopDiv.show();
                        }
                    }else {
                        if(fixTopDiv.is(':visible')){
                            fixTopDiv.hide();
                        }
                    }
                });
                //首行冻结结束
  • 如果没记错的话,仅需要加入如下代码,即可实现首行固定,我没有更改过 控制器 模板 和数据模型;
  • 结果
  • QQ截图20180422001141.png
  • 问题
  • 不知道还有没有更简洁,更简单的办法!
  • 还是有小的瑕疵 下图的这位置不是我们想要的结果,不知如何解决了,希望有大神能给看看啊!
  • QQ截图20180422001401.png
  • 如果同时需要行冻结和列冻结又该如何实现呢?
  • 鸣谢:感谢ID:wakasann在博客分享的内容,祝您健康快乐,事业顺利!-博客地址
  • 如果您觉得帖子的内容对您有帮助,请点赞!请收藏!
最后于 1月前 被bqldragon编辑
最新回复 (1)
  • bqldragon 楼主 28天前
    感谢TA
    0 引用 2
    • 发现了一个巨大的bug,冻结表头对导出功能有影响,导出的表格没有表头。
    • 简易修复的办法,希望大神有更好办法……
    //js中监听导出数据按钮 如果点击了 就移除冻结表头
    $(document).on("click", "[title='导出数据']", function () {
                    $("#shelter").remove();
                    return false;
                });
  • 未登录
    3
返回
发表回复