【问题标题】:Freeze first row and first column of table冻结表格的第一行和第一列
【发布时间】:2017-12-17 16:09:01
【问题描述】:

我正在尝试冻结/锁定表格的第一行和第一列。

我试过给theadposition: absolute;position: fixed;,但看起来很奇怪。

我已经遵循了一些答案,但我仍然对如何制作它感到困惑。

我的 HTML/CSS 代码:

th {    
   font-size: 80%;
   text-align: center;
}
td {
   font-size : 65%;
   white-space: pre;
   text-align: center;
}
.inner {
   overflow-x: scroll;
   overflow-y: scroll;
   width: 300px;
   height: 100px;
}
input {
   font-size : 65%;
}
<body>
  <div class="inner">
    <form method="POST" action="dashboard">
      <table class="table table-bordered">
        <thead>
          <tr>
            <th>ID</th>
            <th>Tanggal</th>
            <th>Judul Pekerjaan</th>
            <th>Deskripsi</th>
            <th>Level</th>
            <th>Category</th>
            <th>Severity</th>
          </tr>
        </thead>
    </form>
        <tbody>
          <tr>
            <td>1</td>
            <td>1 May 2017</td>
            <td>Satu</td>
            <td>Satu</td>
          </tr>
          <tr>
            <td>2</td>
            <td>2 May 2017</td>
            <td>Dua</td>
            <td>Dua</td>
          </tr>
          <tr>
            <td>3</td>
            <td>3 May 2017</td>
            <td>Tiga</td>
            <td>Tiga</td>
          </tr>
          <tr>
            <td>3</td>
            <td>3 May 2017</td>
            <td>Tiga</td>
            <td>Tiga</td>
          </tr>
        </tbody>
      </table>
  </div>
</body>

【问题讨论】:

  • 冻结第一行第一列是什么意思???
  • @Sujith 我的意思是锁定。
  • 简单的方法是使用插件。jqueryscript.net/table/…
  • @NaveenDA 这是一个不错的选择。该插件唯一没有考虑的是第一个单元格(在演示中 - Ano),一旦您开始向任一方向滚动,它就会滚动到视线之外。
  • 这是我的插件,看看我的演示naveenda.github.io/tablenav

标签: javascript php jquery html css


【解决方案1】:

冻结第一行

冻结第一行可以通过将表格主体设置为overflow: auto,并为表格单元格提供固定宽度来完成。 (见示例 1)

冻结第一行和第一列

但是,要使第一行和第一列都具有这种行为,您需要将表格的第一行、第一列和第一个单元格分开,然后不断设置它们的位置滚动事件时,基于表格主体的滚动位置的元素。 (见示例 2)

示例 1:(仅冻结第一行)

table thead tr {
    display: block;
}
table th, table td {
    width: 80px;
}
table tbody {
    display: block;
    height: 90px;
    overflow: auto;
}
th {
    text-align: center;
}
td {
    text-align: center;
    white-space: pre;
}
<table class="table table-bordered">
  <thead>
    <tr>
      <th>ID</th>
      <th>Tanggal</th>
      <th>Judul Pekerjaan</th>
      <th>Deskripsi</th>
      <th>Level</th>
      <th>Category</th>
      <th>Severity</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>1</td>
      <td>1 May 2017</td>
      <td>Satu</td>
      <td>Satu</td>
    </tr>
    <tr>
      <td>2</td>
      <td>2 May 2017</td>
      <td>Dua</td>
      <td>Dua</td>
    </tr>
    <tr>
      <td>3</td>
      <td>3 May 2017</td>
      <td>Tiga</td>
      <td>Tiga</td>
    </tr>
    <tr>
      <td>3</td>
      <td>3 May 2017</td>
      <td>Tiga</td>
      <td>Tiga</td>
    </tr>
    <tr>
      <td>2</td>
      <td>2 May 2017</td>
      <td>Dua</td>
      <td>Dua</td>
    </tr>
    <tr>
      <td>3</td>
      <td>3 May 2017</td>
      <td>Tiga</td>
      <td>Tiga</td>
    </tr>
    <tr>
      <td>3</td>
      <td>3 May 2017</td>
      <td>Tiga</td>
      <td>Tiga</td>
    </tr>
  </tbody>
</table>

示例 2:(冻结第一行和第一列)

$(document).ready(function() {
  $('tbody').scroll(function(e) { 
    $('thead').css("left", -$("tbody").scrollLeft());
    $('thead th:nth-child(1)').css("left", $("tbody").scrollLeft()-5); 
    $('tbody td:nth-child(1)').css("left", $("tbody").scrollLeft()-5); 
  });
});
body {
  margin: 0;
}
th, td {
    text-align: center;
    background-color: white
}
table {
  position: relative;
  width: 400px;
  overflow: hidden;
}
thead {
  position: relative;
  display: block;
  width: 400px;
  overflow: visible;
}
thead th {
  min-width: 80px;
  height: 40px;
}
thead th:nth-child(1) {
  position: relative;
  display: block;
  height: 40px;
  padding-top: 20px;
}
tbody {
  position: relative;
  display: block;
  width: 400px;
  height: 90px;
  overflow: scroll;
}
tbody td {
  min-width: 80px;
}
tbody tr td:nth-child(1) {
  position: relative;
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-bordered">
  <thead>
    <tr>
      <th>ID</th>
      <th>Tanggal</th>
      <th>Judul Pekerjaan</th>
      <th>Deskripsi</th>
      <th>Level</th>
      <th>Category</th>
      <th>Severity</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>1</td>
      <td>1 May 2017</td>
      <td>Satu</td>
      <td>Satu</td>
      <td>5</td>
      <td>Lorem</td>
      <td>Ipsum</td>
    </tr>
    <tr>
      <td>2</td>
      <td>2 May 2017</td>
      <td>Dua</td>
      <td>Dua</td>
    </tr>
    <tr>
      <td>3</td>
      <td>3 May 2017</td>
      <td>Tiga</td>
      <td>Tiga</td>
    </tr>
    <tr>
      <td>3</td>
      <td>3 May 2017</td>
      <td>Tiga</td>
      <td>Tiga</td>
    </tr>
    <tr>
      <td>2</td>
      <td>2 May 2017</td>
      <td>Dua</td>
      <td>Dua</td>
    </tr>
    <tr>
      <td>3</td>
      <td>3 May 2017</td>
      <td>Tiga</td>
      <td>Tiga</td>
    </tr>
    <tr>
      <td>3</td>
      <td>3 May 2017</td>
      <td>Tiga</td>
      <td>Tiga</td>
    </tr>
  </tbody>
</table>

【讨论】:

  • 是的,它有效。但我也需要锁定 ID 列。我该怎么办?
  • 您可以将第一列单元格定位为绝对单元格,确保高度与非绝对单元格相同的最简单方法是再次模拟该列。由于您的第一列是绝对的,因此模仿的列将落后于它,您将永远看不到它。在这种情况下,您的表格需要显示所有行,因为您的第一列被冻结,所以您不能有隐藏的行,如果您有隐藏的行,那么当您向下滚动查看时,您的第一列将与右侧的内容不匹配其他隐藏行
  • @ZulfikarSandyPratama 使用纯 CSS 是不可能实现的。如果您对 JavaScript/jQuery 解决方案持开放态度,请将这些标签添加到您的问题中,以便我可以使用可行的解决方案更新我的答案。
  • @ChavaG 是的,我已经添加了 js 和 jquery 标签
  • @ChavaG 它解决了这个问题。谢谢你的回答!
【解决方案2】:

如果有人遇到这样的问题,这里有一个针对现代浏览器的解决方案,无需使用 jQuery 甚至 JS - 只需纯 HTML 和 CSS。 诀窍是将表格设置为相对位置,将第一行和/或列单元格设置为粘性位置。我明确地添加了背景颜色和 z-index 值以产生这种重叠的感觉。

.wrapper {
  overflow: auto;
  height: 100px;
  width: 200px;
}

table {
  position: relative;
  border-collapse: separate;
  border-spacing: 0;
}

table th,
table td {
  width: 50px;
  padding: 5px;
  background-color: white;
}

table tbody {
  height: 90px;
}

table th {
  text-align: center;
  position: sticky;
  top: 0;
  z-index: 2;
}

table th:nth-child(1) {
  left: 0;
  z-index: 3;
}

table td {
  text-align: center;
  white-space: pre;
}

table tbody tr td:nth-child(1) {
  position: sticky;
  left: 0;
  z-index: 1;
}
<div class="wrapper">
  <table class="table table-bordered">
    <thead>
      <tr>
        <th>Id</th>
        <th>Name</th>
        <th>Age</th>
        <th>Country</th>
        <th>Hobbies</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td>1</td>
        <td>George</td>
        <td>43</td>
        <td>New Zealand</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Ann</td>
        <td>25</td>
        <td>Great Britain</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Alexander</td>
        <td>41</td>
        <td>Spain</td>
      </tr>
      <tr>
        <td>4</td>
        <td>Wasilij</td>
        <td>63</td>
        <td>Ukraine</td>
      </tr>
      <tr>
        <td>1</td>
        <td>George</td>
        <td>43</td>
        <td>New Zealand</td>
      </tr>
      <tr>
        <td>1</td>
        <td>George</td>
        <td>43</td>
        <td>New Zealand</td>
      </tr>
      <tr>
        <td>1</td>
        <td>George</td>
        <td>43</td>
        <td>New Zealand</td>
      </tr>
    </tbody>
  </table>
</div>

【讨论】:

    【解决方案3】:

    我昨天和我的同事一起解决了这个问题。改编后的 CSS 是:

    .pcvBody {
      overflow-x: auto;
      width: calc(100vw - 110px);
    
    }
    /* CSS START for freezing table column*/
    #prodTable {
      position: relative;
      overflow: hidden;
    }
    #prodTable thead {
      position: relative;
      display: block;
      overflow: visible;
    }
    #prodTable thead th {
      min-width: 150px;
      width: 1000px;
    }
    #prodTable thead th:nth-child(1), #prodTable thead th:nth-child(2) {
      position: relative;
      /*display: block;*/
      max-width: 150px;
      width: 50px;
      border-left: 1px solid #ededed;
    }
    #prodTable tbody {
      position: relative;
      display: block;
    
    }
    #prodTable tbody td {
      min-width: 150px;
      width: 1000px;
    }
    #prodTable tbody input {
      max-width: 120px;
    }
    #prodTable tbody tr td:nth-child(1), #prodTable tbody tr td:nth-child(2) {
      position: relative;
      /*display: block;*/
      background-color: white;
      min-height: 20px;
      max-width: 150px;
      width: 50px;
      border-left: 1px solid #ededed;
    }
    /* CSS END for freezing table column*/
    

    而调整后的滚动事件为:

    $('#pcvBody').scroll(function(e) {
      var scrollLeft = $("#pcvBody").scrollLeft();
      //$('#prodTable thead').css("left", -tbodyScrollLeft);
      //$('#prodTable thead th:nth-child(1)').css("left", tbodyScrollLeft - 5); 
      //$('#prodTable tbody td:nth-child(1)').css("left", tbodyScrollLeft - 5); 
      $('#prodTable thead th:nth-child(1)').css("left", scrollLeft); 
      $('#prodTable tbody td:nth-child(1)').css("left", scrollLeft); 
      $('#prodTable thead th:nth-child(2)').css("left", scrollLeft);
      $('#prodTable tbody td:nth-child(2)').css("left", scrollLeft);
    });
    

    此外,我添加了一个“div”来包裹表格。

    【讨论】:

      猜你喜欢
      • 2016-08-15
      • 2018-07-09
      • 2014-11-19
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      相关资源
      最近更新 更多