原生 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]
	
		
	        [...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>

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

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

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

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

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

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

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