原生 jshtml 写一个有固定列滚动的 table

Posted hello,是翠花呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原生 jshtml 写一个有固定列滚动的 table相关的知识,希望对你有一定的参考价值。

原生 js、html 写一个有固定列滚动的 table

像 element-ui 和 ant-ui 这些 UI 库他们提供的 table 组件都是可以设置固定列的,比如左边固定则滚动的时候左边不会随着滚动而看不见,右边固定则右侧一列是固定住不动的。

接下来直接用 html 和 js 来尝试一下这种 table 的效果。

  • 一:固定列
    这里我想使用position: sticky;直接达到相对 table 列的固定效果,不需要改变 dom 的结构。

  • 二:阴影
    阴影的效果是,当 table 往右边滚,则左固定列显示阴影效果;当 table 往左边滚,则右固定列显示阴影;如果同时设置左右列都固定,则临界边不显示阴影而滚动到中间两侧固定列都显示阴影。
    这里我打算通过监听 table 的滚动来控制阴影的展示。

  • 三:高度
    因为直接对 table 进行样式更改,不会改变 table 的 dom 结构,会保留 table 原有的“一列行高变化其它列行高也变化”效果。

  • 四:border 样式
    不使用 table 自带样式(太丑了),随便写几句美化一下。

左边列固定滚动的table
<!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 {
        width: 700px;
      }
      .table-container {
        position: relative;
        overflow: scroll;
      }
      .table .table-container table {
        width: max-content;
      }
      .table table tr {
        position: relative;
      }

      .table table td {
        border-bottom: 1px solid #ebeef5;
        height: 38px;
        font-size: 14px;
        color: #666;
      }
      .table .table-container .fixed {
        position: sticky;
        left: 0;
        background-color: #fff;
      }

      .table .table-container .fixed::after {
        position: absolute;
        top: 0;
        right: 0;
        bottom: -1px;
        width: 30px;
        transform: translateX(100%);
        transition: box-shadow 0.3s;
        content: "";
        pointer-events: none;
      }

      .table .table-container .box-shadow::after {
        box-shadow: rgba(0, 0, 0, 0.12) 10px 0px 8px -8px inset;
      }
    </style>
  </head>
  <body>
    <div class="table">
      <div class="table-container">
        <table border="0" cellspacing="0" cellpadding="0">
          <thead>
            <tr>
              <td width="150" class="fixed">姓名</td>
              <td width="150">类别</td>
              <td width="150">年龄</td>
              <td width="150">身高</td>
              <td width="150">体重</td>
              <td width="150">肤色</td>
              <td width="150">牙齿</td>
              <td width="150">健康</td>
            </tr>
          </thead>

          <tbody>
            <tr>
              <td class="fixed">张三</td>
              <td></td>
              <td>12</td>
              <td>136</td>
              <td>136</td>
              <td></td>
              <td></td>
              <td>良好</td>
            </tr>
            <tr>
              <td class="fixed">张三</td>
              <td></td>
              <td>12</td>
              <td>136</td>
              <td>136</td>
              <td></td>
              <td></td>
              <td>良好</td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
    <script>
      window.onload = function () {
        let doc = document.getElementsByClassName("table-container")[0];
        let leftFixs = doc.getElementsByClassName("fixed");

        doc.addEventListener(
          "scroll",
          function (e) {
            if (e.target.scrollLeft > 0) {
              [...leftFixs].forEach((item) => {
                item.classList.add("box-shadow");
              });
            } else {
              [...leftFixs].forEach((item) => {
                item.classList.remove("box-shadow");
              });
            }
          },
          true
        );
      };
    </script>
  </body>
</html>

右边列固定滚动的table
<!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 {
      width: 700px;      
    }
    .table-container {
      position: relative;
      overflow: scroll;

    }
    .table .table-container table {
      width: max-content;
    }
    .table table tr{
      position: relative;
    }

    .table table td{
      border-bottom: 1px solid #ebeef5;
      height: 38px;
      font-size: 14px;
      color: #666;
      padding: 2px;
    }
    .table .table-container .fixed {
      position: sticky;
      right: 0;
      background-color: #fff;
    }

    .table .table-container .fixed::before {
      position: absolute;
      top: 0;
      bottom: -1px;
      left: 0;
      width: 30px;
      transform: translateX(-100%);
      transition: box-shadow .3s;
      content: '';
      pointer-events: none;
    }

    .table .table-container .box-shadow::before {
      box-shadow: rgba(0,0,0,0.12) -10px 0 8px -8px inset;
    }

  </style>
</head>
<body>
  <div class="table">

    <div class="table-container">

        <table border="0" cellspacing="0" cellpadding="0">
          <thead>
            <tr>
              <td width="150">姓名</td>
              <td width="150">类别</td>
              <td width="150">年龄</td>
              <td width="150">身高</td>
              <td width="150">体重</td>
              <td width="150">肤色</td>
              <td width="150">牙齿</td>
              <td width="150" class="fixed">健康</td>
            </tr>
          </thead>
    
          <tbody>
            <tr>
              <td>张三</td>
              <td></td>
              <td>12</td>
              <td>136</td>
              <td>136</td>
              <td></td>
              <td></td>
              <td class="fixed">良好</td>
            </tr>
            <tr>
              <td>张三</td>
              <td></td>
              <td>12</td>
              <td>136</td>
              <td>136</td>
              <td></td>
              <td></td>
              <td class="fixed">良好</td>
            </tr>
          </tbody>
        </table>

    </div>
   
  </div>
  <script>
    window.onload = function () {
      let doc = document.getElementsByClassName('table-container')[0]

      let rightFixs = doc.getElementsByClassName('fixed')

      let table = doc.getElementsByTagName('table')[0]

      doc.addEventListener('scroll', function(e) {

        if (e.target.scrollLeft < table.clientWidth - doc.clientWidth) {
          [...rightFixs].forEach(item => {
            item.classList.add('box-shadow')
          })
        } else {
          [...rightFixs].forEach(item => {
            item.classList.remove('box-shadow')
          })
        }
      }, true)
    }
  </script>
</body>
</html>

以上是关于原生 jshtml 写一个有固定列滚动的 table的主要内容,如果未能解决你的问题,请参考以下文章

实现固定表头和表列的table组件

实现固定表头和表列的table组件

ElementUI表格合计项固定列 滚动条不可滑动

ElementUI表格合计项固定列 滚动条不可滑动

table固定表头固定列实现横向纵向滚动

ElementUI el-table 固定列后,滚动条在固定列的位置上无法滚动的问题