原生 js、html 写一个有固定列滚动的 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]
	
		{
	        [...rightFixs].forEach(item => {
	          item.classList.add('box-shadow')
	        })
	     }

      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>

在这里插入图片描述

  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
可以通过以下步骤实现使用原生table 固定第一,并且 table 超出可以滚动: 1. 在 table 外层包裹一个 div,设置 div 的宽度和高度,并且添加 overflow 属性为 auto。 2. 将 table 分成两个部分,第一部分只包含第一,第二部分包含剩余的。 3. 使用 CSS 设置第一部分的宽度和样式,使其能够固定在左侧;设置第二部分的样式,使其能够与第一部分对齐。 下面是一个简单的例子代码,可以实现 table 固定第一,并且 table 超出可以滚动: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>固定第一的表格</title> <style> .table-wrapper { width: 300px; height: 200px; overflow: auto; } .table-wrapper table { border-collapse: collapse; width: 100%; } .table-wrapper td, .table-wrapper th { padding: 10px; border: 1px solid #ccc; } .table-wrapper td:first-child, .table-wrapper th:first-child { position: sticky; left: 0; z-index: 1; background-color: #fff; } .table-wrapper td:not(:first-child), .table-wrapper th:not(:first-child) { background-color: #f5f5f5; } </style> </head> <body> <div class="table-wrapper"> <table> <thead> <tr> <th>姓名</th> <th>年龄</th> <th>性别</th> <th>地址</th> </tr> </thead> <tbody> <tr> <td>张三</td> <td>20</td> <td>男</td> <td>北京</td> </tr> <tr> <td>李四</td> <td>25</td> <td>女</td> <td>上海</td> </tr> <tr> <td>王五</td> <td>30</td> <td>男</td> <td>深圳</td> </tr> <tr> <td>赵六</td> <td>35</td> <td>女</td> <td>广州</td> </tr> </tbody> </table> </div> </body> </html> ``` 这段代码会生成一个包含固定第一table,当 table 内容超出 div 的宽度和高度时,div 会出现滚动条。你可以根据自己的需求进行调整。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值