【发布时间】:2018-02-26 18:28:58
【问题描述】:
如何使用现代 CSS 制作尽可能少的 JavaScript 表格?
我想要的功能是:
- 固定列(定位和宽度)
- 可在 X 和 Y 轴上滚动
- 在 X 轴上响应(对于非固定宽度的列)。
注意:我确实看到并分析了 SO 中一些最受欢迎/看到的问题和答案,例如 here 和 here。
我知道这可以通过 JavaScript 滚动事件处理程序来完成,以便可以向下/向上移动固定列以跟随主列。我正在尝试构建的功能示例(但编写了大量脚本)could be like this。我们还可以在表的父元素中添加MutationObserver,以检测大小变化并再次计算表的大小。但这在性能上很昂贵,而且由于 CSS 也在不断发展和现代化,我想知道是否有新的方法......
是否有 2017/2018 解决方案仅使用 CSS 或尽可能少的 JS 开销?
我希望避免实现像这样容易崩溃的 JavaScript 解决方案:
我的想法:
a):在固定列中使用position: fixed;
问题:
-
<td>元素高度必须由 JavaScript 定义或计算。 - 需要一个滚动事件侦听器,我们需要以编程方式滚动固定列
b):使用 div(s) 来“伪造”左列并在表格中显示可滚动的内容
问题:
- div 高度必须与表格行高度同步
- HTML 语义丢失,因为固定的“假”列不再是表格语法
c):使用 N 个表格只显示每个表格的一部分,这样我就可以有 HTML 标记,但保持固定的标题/列。
问题:
- 重复的 HTML x N
- 还必须使用 JavaScript 同步大小和滚动
使用滚动事件监听器和固定的左列,我们可以像这样使用 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 技术来做到这一点。
【问题讨论】:
-
您只想要一个表格,还是可以接受嵌套元素?
-
@klenium 我没有任何愿望,我的想法是让 CSS 进行滚动、调整大小和响应。也许我们还没有 CSS,我们可能需要 JavaScript。如果您有想法,请分享。我命名的问题和链接是一些单表,一些多表。但它们有一些限制和开销,可能在 2018 年我们不再需要 (?)。
-
您的 JS “解决方案”并不完美,在主页滚动时会中断
-
@ZachSaucier 在我的问题中提到了可能的重复项,但它没有我要查找的内容。该问题要求“只冻结一个左列” - 这个问题的范围更广泛,它与固定标题、固定列s 和可滚动正文有关.另一个问题和接受的答案来自 2009 年!我认为这个话题,我的具体范围和例子值得重新审视。另外:我的“JS 解决方案”只是 JS 如何破坏的一个示例,我正在寻找现代 CSS 技术来做到这一点。
标签: javascript html css html-table