table表头和首列的表格固定-JQuery、js实现的Table表头固定

4 篇文章 0 订阅

这个是最简单的方法,基于jQuery的解决方案,引入一个两个js就可以解决,当然也有使用css,
position: sticky,这个我下一章节会讲它的优缺点,当然为了凸显jQuery的优点,
这里写图片描述

我就说话使用css的缺点

1.固定表头,和首列需要额外的html,结构复杂。

2.体验效果,响应式布局很难解决,几乎没有解决
,table固定了长宽,在其他页面会看到很别扭,影响美观。

3.遇到bug,如果你是后端开发就需要找前端一点一点调样式,后端噩梦,影响开发效率

现在开始介绍JQuery的思路:
步骤1:克隆元素
在我们开始之前,我们将要关闭表头,并声明一些变量

//声明屏幕、当前table
    var $ t = $(this),
        $ w = $(window),
        $ thead = $(this).find('thead').clone(),
        $ col = $(this).find('thead,tbody').clone();

步骤2:创建新表
步骤3:插入克隆后的表格内容
步骤4:通过scrollTop算滚动高度来显示新表
算了还是长话短说,不说原理了,具体js代码等下回帖出来,不懂的可以直接问我,直接看看怎么使用吧。

第一步引入js

jquery.stickyheader.js
//可以去这里下载自己重新创建一个
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-throttle-debounce/1.1/jquery.ba-throttle-debounce.min.js"></script>

第二步html中table结构

<table>
    <thead>
        <tr>
        <!-- 固定表头是th里面的内容 -->
            <th></th>
            
    </tr>
    </thead>
    <tbody>
        <tr>
         <!-- 如果你需要列表的第一列也固定 -->
         <!-- <th></th> 使用这种模式支持rowspan -->
            <td></td>
           
        </tr>
        <!-- more rows are possible -->
    </tbody>

</table>

css

.sticky-wrap {
    overflow-x: auto;
    position: relative;
    margin-bottom: 1.5em;
    width: 100%;
}
.sticky-wrap .sticky-thead,
.sticky-wrap .sticky-col,
.sticky-wrap .sticky-intersect {
    opacity: 0;
    position: absolute;
    top: 0;
    left: 0;
    transition: all .125s ease-in-out;
    z-index: 50;
    width: auto; /* Prevent table from stretching to full size */
}
    .sticky-wrap .sticky-thead {
        box-shadow: 0 0.25em 0.1em -0.1em rgba(0,0,0,.125);
        z-index: 100;
        width: 100%; /* Force stretch */
    }
    .sticky-wrap .sticky-intersect {
        opacity: 1;
        z-index: 150;
    }
    .sticky-wrap .sticky-intersect th {
        background-color: #666;
        color: #eee;
    }
.sticky-wrap td,
.sticky-wrap th {
    box-sizing: border-box;
}

第三步打开浏览器看效果吧

这里写图片描述

原文

  1. 在线演示1
  2. 在线演示2
  3. 在线演示3

jquery-throttle-debounce-plugin.js

(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);

jquery.stickyheader.js

 $('table').each(function() {
            if($(this).find('thead').length > 0 && $(this).find('th').length > 0) {
                // 克隆<thead>
                var $w	   = $(window),
                        $t	   = $(this),
                        $thead = $t.find('thead').clone(),
                        $col   = $t.find('thead, tbody').clone();

                // Add class, remove margins, reset width and wrap table
                $t
                        .addClass('sticky-enabled')
                        .css({
                            margin: 0,
                            width: '100%'
                        }).wrap('<div class="sticky-wrap" />');

                if($t.hasClass('overflow-y')) $t.removeClass('overflow-y').parent().addClass('overflow-y');

                // Create new sticky table head (basic)
                $t.after('<table class="sticky-thead table" />');

                // If <tbody> contains <th>, then we create sticky column and intersect (advanced)
                if($t.find('tbody th').length > 0) {
                    $t.after('<table class="sticky-col table" /><table class="sticky-intersect" />');
                }

                // Create shorthand for things
                var $stickyHead  = $(this).siblings('.sticky-thead'),
                        $stickyCol   = $(this).siblings('.sticky-col'),
                        $stickyInsct = $(this).siblings('.sticky-intersect'),
                        $stickyWrap  = $(this).parent('.sticky-wrap');

                $stickyHead.append($thead);

                $stickyCol
                        .append($col)
                        .find('thead th:gt(0)').remove()
                        .end()
                        .find('tbody td').remove();

                $stickyInsct.html('<thead><tr><th>'+$t.find('thead th:first-child').html()+'</th></tr></thead>');

                // 设置宽度
                var setWidths = function () {
                            $t
                                    .find('thead th').each(function (i) {
                                $stickyHead.find('th').eq(i).width($(this).width());
                            })
                                    .end()
                                    .find('tr').each(function (i) {
                                $stickyCol.find('tr').eq(i).height($(this).height());
                            });

                            // Set width of sticky table head
                            $stickyHead.width($t.width());

                            // Set width of sticky table col
                            $stickyCol.find('th').add($stickyInsct.find('th')).width($t.find('thead th').width())
                        },
                        repositionStickyHead = function () {
                            // Return value of calculated allowance
                            var allowance = calcAllowance();

                            // Check if wrapper parent is overflowing along the y-axis
                            if($t.height() > $stickyWrap.height()) {
                                // If it is overflowing (advanced layout)
                                // Position sticky header based on wrapper scrollTop()
                                if($stickyWrap.scrollTop() > 0) {
                                    // When top of wrapping parent is out of view
                                    $stickyHead.add($stickyInsct).css({
                                        opacity: 1,
                                        top: $stickyWrap.scrollTop()
                                    });
                                } else {
                                    // When top of wrapping parent is in view
                                    $stickyHead.add($stickyInsct).css({
                                        opacity: 0,
                                        top: 0
                                    });
                                }
                            } else {
                                // If it is not overflowing (basic layout)
                                // Position sticky header based on viewport scrollTop
                                if($w.scrollTop() > $t.offset().top && $w.scrollTop() < $t.offset().top + $t.outerHeight() - allowance) {
                                    // When top of viewport is in the table itself
                                    $stickyHead.add($stickyInsct).css({
                                        opacity: 1,
                                        top: $w.scrollTop() - $t.offset().top
                                    });
                                } else {
                                    // When top of viewport is above or below table
                                    $stickyHead.add($stickyInsct).css({
                                        opacity: 0,
                                        top: 0
                                    });
                                }
                            }
                        },
                        repositionStickyCol = function () {
                            if($stickyWrap.scrollLeft() > 0) {
                                // When left of wrapping parent is out of view
                                $stickyCol.add($stickyInsct).css({
                                    opacity: 1,
                                    left: $stickyWrap.scrollLeft()
                                });
                            } else {
                                // When left of wrapping parent is in view
                                $stickyCol
                                        .css({ opacity: 0 })
                                        .add($stickyInsct).css({ left: 0 });
                            }
                        },
                        calcAllowance = function () {
                            var a = 0;
                            // Calculate allowance
                            $t.find('tbody tr:lt(3)').each(function () {
                                a += $(this).height();
                            });

                            // Set fail safe limit (last three row might be too tall)
                            // Set arbitrary limit at 0.25 of viewport height, or you can use an arbitrary pixel value
                            if(a > $w.height()*0.25) {
                                a = $w.height()*0.25;
                            }

                            // Add the height of sticky header
                            a += $stickyHead.height();
                            return a;
                        };

                setWidths();

                $t.parent('.sticky-wrap').scroll($.throttle(250, function() {
                    repositionStickyHead();
                    repositionStickyCol();
                }));

                $w
                        .load(setWidths)
                        .resize($.debounce(250, function () {
                            setWidths();
                            repositionStickyHead();
                            repositionStickyCol();
                        }))
                        .scroll($.throttle(250, repositionStickyHead));
            }
        });

2018.7.13 又发现一个好插件,如果你用过datatable可以使用fixedheader来固定头部,使用fixedcolumns固定列
https://datatables.net/extensions/fixedheader/
2018.11.27 又发现一个插件
https://github.com/harryluo163/toutiao/tree/master/CSS实现的Table表头固定
http://47.105.36.188:3030/toutiao/CSS实现的Table表头固定/index.html
如果你遇到问题,可以加群315552185
一起交流哦!

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值