滚动吸附(Scroll Snap)可以让表格在滚动时自动对齐到行或列的边界,提供更好的用户体验。以下是原生JS实现方案:
.scroll-container {
overflow: auto;
scroll-snap-type: y mandatory; /* 垂直方向吸附 */
height: 300px; /* 固定高度 */
}
.scroll-item {
scroll-snap-align: start; /* 吸附到起始位置 */
}
const table = document.querySelector('.scroll-container');
let isScrolling = false;
table.addEventListener('scroll', () => {
if (!isScrolling) {
window.requestAnimationFrame(() => {
const rowHeight = 40; // 每行高度
const snapPosition = Math.round(table.scrollTop / rowHeight) * rowHeight;
table.scrollTop = snapPosition;
isScrolling = false;
});
isScrolling = true;
}
});
function toggleColumn(columnIndex, show) {
const table = document.getElementById('myTable');
const rows = table.rows;
for (let i = 0; i < rows.length; i++) {
const cell = rows[i].cells[columnIndex];
cell.style.display = show ? '' : 'none';
}
}
// 隐藏第2列(索引从0开始)
toggleColumn(1, false);
function toggleRow(rowIndex, show) {
const table = document.getElementById('myTable');
const row = table.rows[rowIndex];
row.style.display = show ? '' : 'none';
}
// 隐藏第3行
toggleRow(2, false);
function filterRows(columnIndex, filterValue) {
const table = document.getElementById('myTable');
const rows = table.rows;
for (let i = 1; i < rows.length; i++) { // 从1开始跳过表头
const cell = rows[i].cells[columnIndex];
const match = cell.textContent.includes(filterValue);
rows[i].style.display = match ? '' : 'none';
}
}
// 只显示"状态"列包含"完成"的行
filterRows(3, "完成");
<!DOCTYPE html>
<html>
<head>
<style>
.table-container {
width: 100%;
overflow: auto;
height: 300px;
scroll-snap-type: y mandatory;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
scroll-snap-align: start;
}
th {
background-color: #f2f2f2;
position: sticky;
top: 0;
}
.controls {
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="controls">
<button onclick="toggleColumn(1, false)">隐藏第二列</button>
<button onclick="toggleColumn(1, true)">显示第二列</button>
<button onclick="filterRows(2, '完成')">只显示完成项</button>
</div>
<div class="table-container" id="tableContainer">
<table id="myTable">
<thead>
<tr>
<th>ID</th>
<th>名称</th>
<th>状态</th>
<th>日期</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>项目A</td><td>进行中</td><td>2023-01-01</td></tr>
<tr><td>2</td><td>项目B</td><td>完成</td><td>2023-01-02</td></tr>
<!-- 更多行... -->
</tbody>
</table>
</div>
<script>
// 滚动吸附增强
const container = document.getElementById('tableContainer');
let isScrolling = false;
container.addEventListener('scroll', () => {
if (!isScrolling) {
window.requestAnimationFrame(() => {
const rowHeight = 40; // 根据实际行高调整
const snapPosition = Math.round(container.scrollTop / rowHeight) * rowHeight;
container.scrollTop = snapPosition;
isScrolling = false;
});
isScrolling = true;
}
});
// 列显示/隐藏
function toggleColumn(columnIndex, show) {
const table = document.getElementById('myTable');
const rows = table.rows;
for (let i = 0; i < rows.length; i++) {
const cell = rows[i].cells[columnIndex];
if (cell) cell.style.display = show ? '' : 'none';
}
}
// 行过滤
function filterRows(columnIndex, filterValue) {
const table = document.getElementById('myTable');
const rows = table.rows;
for (let i = 1; i < rows.length; i++) {
const cell = rows[i].cells[columnIndex];
const match = cell.textContent.includes(filterValue);
rows[i].style.display = match ? '' : 'none';
}
}
</script>
</body>
</html>
requestAnimationFrame
优化滚动性能Intersection Observer
API来检测元素可见性这些原生JS实现方案可以根据具体需求进行调整和扩展。