[英]Scrollable table with fixed columns and header, with modern CSS
如何使用现代 CSS 用尽可能少的 JavaScript 制作表格?
我试图拥有的功能是:
注意:我确实看到并分析了 SO 中一些最受欢迎/看到的问题和答案,例如这里和这里。
我知道这可以通过用于滚动的 JavaScript 事件处理程序来完成,以便固定列可以向下/向上移动以跟随主列。 我正在尝试构建(但大量脚本)的功能示例可能是这样的。 我们还可以在表的父元素中添加MutationObserver
来检测大小变化并再次计算表的大小。 但这在性能上很昂贵,而且由于 CSS 也在不断发展和现代化,我想知道是否有新的方法......
是否有一个 2017/2018 解决方案,它只有 CSS 或尽可能少的 JS 开销?
我想避免必须实现像这样容易崩溃的 JavaScript 解决方案:
我的想法:
a)
:使用position: fixed;
在固定列中
问题:
<td>
元素的高度必须由 JavaScript 定义或计算。 b)
: 使用 div(s) 来“伪造”左列并在表格中包含可滚动的内容
问题:
c)
:使用N 个表格只显示每个表格的一部分,这样我就可以使用 HTML 标记但保留固定的标题/列。
问题:
使用滚动事件侦听器和固定的左列,我们可以像这样使用 JavaScript:
const firstColumn = [...document.querySelectorAll('table tr > *:first-of-type')]; const tableContainer = document.querySelector('.table-container'); tableContainer.addEventListener('scroll', function() { const currentScrollPosition = this.scrollTop * -1; firstColumn.forEach(el => el.style.marginTop = currentScrollPosition + 'px'); });
.table-container { width: 600px; height: 300px; overflow-x: scroll; overflow-y: scroll; } .table-scroller { width: 1000px; } table { width: 100%; margin-left: -13px; table-layout: fixed; border-collapse: collapse; border: none; } table th, table td { padding: 0.8em; border: 1px solid; background-color: #eeeeef; } table th { background-color: #6699FF; font-weight: bold; } table tr { height: 60px; vertical-align: middle; } table tr > *:first-of-type { position: fixed; width: 50px; margin-left: 13px; margin-top: 0; height: inherit; }
<div class="table-container"> <div class="table-scroller"> <table> <tbody> <tr> <td>Edrward 0</td> <td>32</td> <td>London Park no. 0</td> <td>London Park no. 0</td> <td>London Park no. 0</td> <td>London Park no. 0</td> <td>London Park no. 0</td> <td>London Park no. 0</td> <td>London Park no. 0</td> <td>London Park no. 0</td> <td><a href="#">action</a></td> </tr> <tr> <td>Edrward 1</td> <td>32</td> <td>London Park no. 1</td> <td>London Park no. 1</td> <td>London Park no. 1</td> <td>London Park no. 1</td> <td>London Park no. 1</td> <td>London Park no. 1</td> <td>London Park no. 1</td> <td>London Park no. 1</td> <td><a href="#">action</a></td> </tr> <tr> <td>Edrward 2</td> <td>32</td> <td>London Park no. 2</td> <td>London Park no. 2</td> <td>London Park no. 2</td> <td>London Park no. 2</td> <td>London Park no. 2</td> <td>London Park no. 2</td> <td>London Park no. 2</td> <td>London Park no. 2</td> <td><a href="#">action</a></td> </tr> <tr> <td>Edrward 3</td> <td>32</td> <td>London Park no. 3</td> <td>London Park no. 3</td> <td>London Park no. 3</td> <td>London Park no. 3</td> <td>London Park no. 3</td> <td>London Park no. 3</td> <td>London Park no. 3</td> <td>London Park no. 3</td> <td><a href="#">action</a></td> </tr> <tr> <td>Edrward 4</td> <td>32</td> <td>London Park no. 4</td> <td>London Park no. 4</td> <td>London Park no. 4</td> <td>London Park no. 4</td> <td>London Park no. 4</td> <td>London Park no. 4</td> <td>London Park no. 4</td> <td>London Park no. 4</td> <td><a href="#">action</a></td> </tr> <tr> <td>Edrward 5</td> <td>32</td> <td>London Park no. 5</td> <td>London Park no. 5</td> <td>London Park no. 5</td> <td>London Park no. 5</td> <td>London Park no. 5</td> <td>London Park no. 5</td> <td>London Park no. 5</td> <td>London Park no. 5</td> <td><a href="#">action</a></td> </tr> <tr> <td>Edrward 6</td> <td>32</td> <td>London Park no. 6</td> <td>London Park no. 6</td> <td>London Park no. 6</td> <td>London Park no. 6</td> <td>London Park no. 6</td> <td>London Park no. 6</td> <td>London Park no. 6</td> <td>London Park no. 6</td> <td><a href="#">action</a></td> </tr> <tr> <td>Edrward 7</td> <td>32</td> <td>London Park no. 7</td> <td>London Park no. 7</td> <td>London Park no. 7</td> <td>London Park no. 7</td> <td>London Park no. 7</td> <td>London Park no. 7</td> <td>London Park no. 7</td> <td>London Park no. 7</td> <td><a href="#">action</a></td> </tr> <tr> <td>Edrward 8</td> <td>32</td> <td>London Park no. 8</td> <td>London Park no. 8</td> <td>London Park no. 8</td> <td>London Park no. 8</td> <td>London Park no. 8</td> <td>London Park no. 8</td> <td>London Park no. 8</td> <td>London Park no. 8</td> <td><a href="#">action</a></td> </tr> <tr> <td>Edrward 9</td> <td>32</td> <td>London Park no. 9</td> <td>London Park no. 9</td> <td>London Park no. 9</td> <td>London Park no. 9</td> <td>London Park no. 9</td> <td>London Park no. 9</td> <td>London Park no. 9</td> <td>London Park no. 9</td> <td><a href="#">action</a></td> </tr> </tbody> </table> </div> </div>
但是我可以在没有 JavaScript 的情况下做到这一点吗?
关于可能的重复建议:
我的问题中提到了可能的重复项,但它没有我正在寻找的内容。 这个问题要求“只冻结一个左列” - 这个问题的范围更广泛,它与固定标题、固定列和可滚动正文有关。
另一个问题和接受的答案来自 2009 年! 我认为这个话题,以及我的具体范围和例子值得重新审视。 另外:我的“JS 解决方案”只是 JS 如何破坏的一个例子,我正在寻找现代 CSS 技术来做到这一点。
也许您可以尝试使用最近的position:sticky
来实现它。 或者,至少,以较少的 javascript 开始该方法。
div{ overflow:auto; width:100%; height:200px; } td, th { border: 1px solid #000; width: 100px; } th {background-color:red;} table { table-layout: fixed; width:100%; } td:first-child, th:first-child { position:sticky; left:0; z-index:1; background-color:grey; } td:last-child, th:last-child { position:sticky; right:0; z-index:1; background-color:blue; } thead tr th { position:sticky; top:0; } th:first-child, th:last-child {z-index:2;background-color:red;}
<div> <table> <thead> <tr> <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> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> </tbody> </table> </div>
只需查看带有固定标题的代码并修复第一列即可。
<style type="text/css">
.table {
font-family: arial, sans-serif;
border-collapse: collapse;
}
.th {
width: 126px;
height: 56px;
padding: 0px 16px;
text-align: left;
background-color: #fafafa;
}
.td {
width: 118px;
min-width: 118px;
max-width: 118px;
height: 56px;
max-height: 56px;
overflow: hidden;
text-align: center;
border-bottom: 2px solid #dddddd;
}
.pink_color {
background-color: pink;
}
.table_wrapper {
position: relative;
}
.table_scroll {
height: 73vh;
overflow: auto;
}
.table_wrapper table {
width: 100%;
}
.table_wrapper table thead th .text {
position: absolute;
z-index: 2;
}
.tableFixHead
{
overflow: auto; height: 63vh;
}
.tableFixHead thead th
{
position: sticky; top: 0; z-index: 1;
}
@media only screen and (min-width: 1440px) {
.table_scroll {
height: 77vh;
overflow: auto;
}
}
</style>
<div style="padding-top: 16px;">
<div class="table_wrapper">
<div class="tableFixHead">
<table class="table">
<thead>
<th style="position: sticky; left: 0; z-index: 3;" class="text th"></th>
<th class="text th">1</th>
<th class="text th">1</th>
<th class="text th">1</th>
<th class="text th">1</th>
<th class="text th">1</th>
<th class="text th">1</th>
<th class="text th">1</th>
<th class="text th">1</th>
<th class="text th">1</th>
<th class="text th">1</th>
<th class="text th">1</th>
<th class="text th">1</th>
<th class="text th">1</th>
</thead>
<tr>
<td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
</tr>
<tr>
<td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
</tr>
<tr>
<td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
</tr><tr>
<td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
</tr><tr>
<td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
</tr><tr>
<td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
</tr><tr>
<td style="position: sticky; left: 0; z-index: 2; background: #fafafa;" class="td">test</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
<td class="td">test1</td>
</tr>
</table>
</div>
</div>
</div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.