在 JS 中滚动到视图
Scroll into view in JS
我有一个HTML代码,有一个大table。我需要滚动才能访问所有行。
然后我将 thead
设为粘性标签。因为我到处都需要这个标签。 (position: sticky; top: 0;
)
但是,当我想在 JavaScript 中使用 firstCell.scrollIntoView();
时,firstCell
将被 thead
覆盖!
您可以在 this link
中查看示例
在此示例中,Target
是 Table 中的第一个 cell
,并且通过单击按钮,它必须滚动到 Target
的视图中
但是 Target
会在 thead
的后面
我该如何解决这个问题?
滚动到视图后,检查头部底部是否与目标顶部重叠 getBoundingClientRect
s。如果是,则调用 window.scrollBy
差值。
const headTr = document.querySelector('thead tr');
document.querySelector('button').addEventListener('click', () => {
const target = document.getElementById('target');
target.scrollIntoView();
const diff = target.getBoundingClientRect().top - target.getBoundingClientRect().bottom;
if (diff < 0) {
window.scrollBy(0, diff);
}
});
<button style="position: fixed; top: 5px; right: 5px;">ScrollIntoView (for Target)</button>
<table>
<thead>
<tr style='position: sticky; top: 0;'>
<td>XYZ</td>
<td>XYZ</td>
<td>XYZ</td>
<td>XYZ</td>
<td>XYZ</td>
</tr>
</thead>
<tbody>
<tr>
<td id=target style="color: red;">Target</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
</tr>
</tbody>
</table>
由于 thead
有一个固定位置,在计算可用 space 时不会考虑它的大小。
解决方法是使用 scrollIntoView({ behavior: 'smooth', block: 'end' })
代替 scrollIntoView()
。
这只有效,因为 thead
的高度等于 tr
的高度,所以如果它使滚动条与底部对齐,它就不会再被覆盖。
我有一个HTML代码,有一个大table。我需要滚动才能访问所有行。
然后我将 thead
设为粘性标签。因为我到处都需要这个标签。 (position: sticky; top: 0;
)
但是,当我想在 JavaScript 中使用 firstCell.scrollIntoView();
时,firstCell
将被 thead
覆盖!
您可以在 this link
中查看示例在此示例中,Target
是 Table 中的第一个 cell
,并且通过单击按钮,它必须滚动到 Target
的视图中
但是 Target
会在 thead
我该如何解决这个问题?
滚动到视图后,检查头部底部是否与目标顶部重叠 getBoundingClientRect
s。如果是,则调用 window.scrollBy
差值。
const headTr = document.querySelector('thead tr');
document.querySelector('button').addEventListener('click', () => {
const target = document.getElementById('target');
target.scrollIntoView();
const diff = target.getBoundingClientRect().top - target.getBoundingClientRect().bottom;
if (diff < 0) {
window.scrollBy(0, diff);
}
});
<button style="position: fixed; top: 5px; right: 5px;">ScrollIntoView (for Target)</button>
<table>
<thead>
<tr style='position: sticky; top: 0;'>
<td>XYZ</td>
<td>XYZ</td>
<td>XYZ</td>
<td>XYZ</td>
<td>XYZ</td>
</tr>
</thead>
<tbody>
<tr>
<td id=target style="color: red;">Target</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
<td>abc</td>
</tr>
</tr>
</tbody>
</table>
由于 thead
有一个固定位置,在计算可用 space 时不会考虑它的大小。
解决方法是使用 scrollIntoView({ behavior: 'smooth', block: 'end' })
代替 scrollIntoView()
。
这只有效,因为 thead
的高度等于 tr
的高度,所以如果它使滚动条与底部对齐,它就不会再被覆盖。