固定表头、固定列的表格实现

514 阅读2分钟

最近碰到这样一个需求,需要固定表头以及列的表格,而且表格需要实现拖拽功能。

实现固定表头以及列的表格

1. stick以及table-layout来实现

主要是使用2个css属性

  • table-layout: fixed 表格和列的宽度通过表格的宽度来设置,某一列的宽度仅由该列首行的单元格决定。在当前列中,该单元格所在行之 后的行并不会影响整个列宽。
table {
   table-layout: fixed;
   width: 100%;
}
  • position:sticky 根据正常文档流进行定位,相对它的最近滚动祖先,基于top,right,bottom和left的值进行偏移。偏移值不会影响任何其他的元素。 sticky的表现相似于relative和fixed的合体,在超过目标区域时,他会固定于目标位置。
thead tr th{
    position:sticky;
    top:0;
}

代码如下:

    <!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>React Webpack Template Title</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <style>
      .test-table {
        width:800px;
        height:240px; /* 固定高度 */
        margin: 0 auto;
        border:1px solid gray;
        border-bottom: 0;
        border-right: 0;
        text-align: center;
        overflow:auto;
    }
    td, th {
      border-right :1px solid gray;
      border-bottom :1px solid gray;
      width:100px;
      height:30px;
      box-sizing: border-box;
    }
    th {
        background-color:lightblue;
    }
    table {
        border-collapse:separate;
        table-layout: fixed;
        width: 100%; /* 固定寬度 */
    }
    td:first-child, th:first-child {
        position:sticky;
        left:0; /* 首行在左 */
        z-index:1;
        background-color:lightpink;
    }

    thead tr th {
        position:sticky;
        top:0; /* 第一列最上 */
    }

    th:first-child{
        z-index:2;
        background-color:lightblue;
    }
  </style>
</head>
<body>
    <div class="test-table">
        <table cellSpacing="0" cellPadding="0">
          <thead>
            <tr>
              <th>学号</th>
              <th>姓名</th>
              <th>年龄</th>
              <th>性别</th>
              <th>爱好</th>
              <th>语文</th>
              <th>数学</th>
              <th>英语</th>
              <th>历史</th>
              <th>地理</th>
              <th>物理</th>
              <th>化学</th>
              <th>政治</th>
              <th>体育</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>wx001</td>
              <td>张三</td>
              <td>14</td>
              <td></td>
              <td>毛笔字</td>
              <td>92</td>
              <td>99</td>
              <td>90</td>
              <td>94</td>
              <td>91</td>
              <td>90</td>
              <td>95</td>
              <td>90</td>
              <td>100</td>
            </tr>
            <tr>
              <td>wx002</td>
              <td>李四</td>
              <td>14</td>
              <td></td>
              <td>跳舞</td>
              <td>92</td>
              <td>99</td>
              <td>90</td>
              <td>94</td>
              <td>91</td>
              <td>90</td>
              <td>95</td>
              <td>90</td>
              <td>100</td>
            </tr>
            <tr>
              <td>wx003</td>
              <td>王五</td>
              <td>14</td>
              <td></td>
              <td>音乐</td>
              <td>92</td>
              <td>99</td>
              <td>90</td>
              <td>94</td>
              <td>91</td>
              <td>90</td>
              <td>95</td>
              <td>90</td>
              <td>100</td>
            </tr>
            <tr>
              <td>wx004</td>
              <td>何马</td>
              <td>14</td>
              <td></td>
              <td>跳舞</td>
              <td>92</td>
              <td>99</td>
              <td>90</td>
              <td>94</td>
              <td>91</td>
              <td>90</td>
              <td>95</td>
              <td>90</td>
              <td>100</td>
            </tr>
            <tr>
              <td>wx005</td>
              <td>谢谢</td>
              <td>15</td>
              <td></td>
              <td>画画</td>
              <td>92</td>
              <td>99</td>
              <td>90</td>
              <td>94</td>
              <td>91</td>
              <td>90</td>
              <td>95</td>
              <td>90</td>
              <td>100</td>
            </tr>
            <tr>
              <td>wx006</td>
              <td>李西</td>
              <td>14</td>
              <td></td>
              <td>跳舞</td>
              <td>92</td>
              <td>99</td>
              <td>90</td>
              <td>94</td>
              <td>91</td>
              <td>90</td>
              <td>95</td>
              <td>90</td>
              <td>100</td>
            </tr>
            <tr>
              <td>wx007</td>
              <td>照照</td>
              <td>14</td>
              <td></td>
              <td>跳舞</td>
              <td>92</td>
              <td>99</td>
              <td>90</td>
              <td>94</td>
              <td>91</td>
              <td>90</td>
              <td>95</td>
              <td>90</td>
              <td>100</td>
            </tr>
            <tr>
              <td>wx008</td>
              <td>阳阳</td>
              <td>15</td>
              <td></td>
              <td>跳舞</td>
              <td>92</td>
              <td>99</td>
              <td>90</td>
              <td>94</td>
              <td>91</td>
              <td>90</td>
              <td>95</td>
              <td>90</td>
              <td>100</td>
            </tr>
            <tr>
              <td>wx009</td>
              <td>浩浩</td>
              <td>14</td>
              <td></td>
              <td>跳舞</td>
              <td>92</td>
              <td>99</td>
              <td>90</td>
              <td>94</td>
              <td>91</td>
              <td>90</td>
              <td>95</td>
              <td>90</td>
              <td>100</td>
            </tr>
          </tbody>
        </table>
      </div>
</body>
</html>

具体效果DEMO

2. 固定表头和列

参考文章

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
     .table {
        display: table;
        border-collapse: separate;
        border-spacing: 0;
        border-color: grey;
    }
    td {
        padding: 4px;
        /* border: 1px solid #e6e6e6;  */
        background: lightblue;
        border-right: 1px solid gray;
        border-bottom: 1px solid gray;
    }
    .table-box{
        position: relative;
        padding: 0;
        width: 710px;
        background-color: rgb(255, 255, 255);
        margin-bottom: 5px;
        border: 1px solid gray;
        margin: 0 auto;
    }
    .table-left-box {
        overflow: hidden;
        top: 0;
        left: 0;
        max-width: 90px;
        z-index: 100
    }
    .table-right-box {
        position: absolute;
        overflow: hidden;
        top: 0;
        right: 0;
        width: 621px;
    }
    .table-left-body td {
        border-top: none;
        background: lightpink;
    }
    .table-right-body td {
            border-top: none;
            background: #ffffff;
    }
    .table-left-body {
        overflow-x: hidden;
        overflow-y: hidden;
        max-width: 90px;
        max-height: 174px;
    }
    .table-left-body .table-left-text{
            width: 80px;
            height: 35px;
            line-height: 35px;
    }
    .table-right-body {
        overflow-x: auto;
        overflow-y: auto;
        width: 100%;
        max-height: 174px;
    }
    .table-right-header{
        width: 100%;
        overflow-x: hidden;
        overflow-y: hidden;
    }
    .table-right-text{
        width: 160px;
        height: 35px;
        line-height: 35px;
    }
  </style>
</head>
<body>
  <div class="table-box">
    <div class="table-left-box">
        <div class="table-left-header">
            <div>
                <table border="0" cellspacing="0" cellpadding="0">
                    <tbody>
                        <tr>
                            <td class="td color">
                                <div style="width: 80px;height: 35px;line-height: 35px;">
                                    学号
                                </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <div ref="bodyWrapperLeft" class="table-left-body">
            <div style="padding-bottom: 20px;box-sizing: border-box;">
                <table border="0" cellspacing="0" cellpadding="0">
                    <tbody>
                        <tr>
                            <td>
                                <div class="table-left-text">
                                  wx001
                                </div>
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <div class="table-left-text">
                                  wx002
                                </div>
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <div class="table-left-text">
                                  wx003
                                </div>
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <div class="table-left-text">
                                  wx004
                                </div>
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <div class="table-left-text">
                                  wx005
                                </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
    <div class="table-right-box">
        <div ref="headerWrapper" class="table-right-header">
            <div style="width: 10000px;">
                <table border="0" cellspacing="0" cellpadding="0" class="">
                    <tbody>
                      <tr>
                          <td>
                              <div class="table-right-text">
                                年龄
                              </div>
                          </td>
                          <td>
                              <div class="table-right-text">
                                性别
                              </div>
                          </td>
                          <td>
                              <div class="table-right-text">
                                爱好
                              </div>
                          </td>
                          <td>
                              <div class="table-right-text">
                                语文
                              </div>
                          </td>
                          <td>
                              <div class="table-right-text">
                                数学
                              </div>
                          </td>
                      </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <div ref="bodyWrapper" class="table-right-body">
            <table border="0" cellspacing="0" cellpadding="0">
              <tbody>
                <tr>
                  <td>
                      <div class="table-right-text">
                        14
                      </div>
                  </td>
                  <td>
                      <div class="table-right-text">
                        男
                      </div>
                  </td>
                  <td>
                      <div class="table-right-text">
                        毛笔字
                      </div>
                  </td>
                  <td>
                      <div class="table-right-text">
                        92
                      </div>
                  </td>
                  <td>
                      <div class="table-right-text">
                        99
                      </div>
                  </td>
              </tr>  
              <tr>
                <td>
                    <div class="table-right-text">
                      14
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      男
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      毛笔字
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      92
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      99
                    </div>
                </td>
            </tr>
            <tr>
                <td>
                    <div class="table-right-text">
                      14
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      男
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      毛笔字
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      92
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      99
                    </div>
                </td>
            </tr>
            <tr>
                <td>
                    <div class="table-right-text">
                      14
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      男
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      毛笔字
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      92
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      99
                    </div>
                </td>
            </tr>
            <tr>
                <td>
                    <div class="table-right-text">
                      14
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      男
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      毛笔字
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      92
                    </div>
                </td>
                <td>
                    <div class="table-right-text">
                      99
                    </div>
                </td>
            </tr>   
              </tbody>
            </table>
        </div>
    </div>
</div>
<script>
    function $(select){
      return document.querySelector(select)
    }
    let bodyWrapper = $('.table-right-body')
    let bodyWrapperLeft = $('.table-left-body')
    let headerWrapper = $('.table-right-header')
    bodyWrapper.addEventListener('scroll', resetPosition, { passive: true });
    function resetPosition() {
        const {
            scrollLeft, scrollTop, offsetWidth, scrollWidth
        } = bodyWrapper;
        if (bodyWrapperLeft) bodyWrapperLeft.scrollTop = scrollTop;
        if (headerWrapper) headerWrapper.scrollLeft = scrollLeft;
    }
</script>
</body>
</html>