我有一个页面,其中一个滚动条包含从数据库动态生成的带有div的表行。每个表行就像一个链接,有点像你在视频播放器旁边看到的YouTube播放列表。
当用户访问页面时,他们所在的选项应该会转到滚动div的顶部。这个功能正在工作。问题是,这有点太过分了。比如他们的选项高了10像素。因此,页面被访问,url被用来识别选择了哪个选项,然后将该选项滚动到滚动div的顶部。注意:这不是窗口的滚动条,这是一个带有滚动条的div。
我正在使用这段代码,使它移动选中的选项到div的顶部:
var pathArray = window.location.pathname.split( '/' );
var el = document.getElementById(pathArray[5]);
el.scrollIntoView(true);
它将它移动到div的顶部,但大约10个像素太高了。
有人知道怎么解决吗?
CSS滚动边距和滚动填充
你可能想看看新的CSS属性滚动填充和滚动边距。可以对滚动容器(在本例中为html)使用滚动填充,对容器内的元素使用滚动边距。
在你的例子中,你想为你想要滚动到视图中的元素添加scroll-margin-top,如下所示:
.example {
scroll-margin-top: 10px;
}
这会影响scrollIntoView代码,如下所示:
const el = document.querySelector(".example");
el.scrollIntoView({block: "start", behavior: "smooth"});
这将导致视口滚动以使视口的上边界与元素的上边界对齐,但有10px的额外空间。换句话说,元素的这些属性被考虑在内:
padding-top
border-top
scroll-margin-top
(而不是margin-top)
此外,如果html元素有滚动填充顶部设置,那么也会考虑这一点。
对于表行中的元素,使用JQuery获取所需元素的上方行,然后简单地滚动到该行。
假设我在一个表中有多行,其中一些行应该由和admin检查。需要审查的每一行都有向上和向下的箭头,引导您到上一项或下一项进行审查。
这是一个完整的例子,如果你在记事本中创建一个新的HTML文档并保存它,它应该会运行。还有额外的代码来检测项目的顶部和底部以进行检查,这样我们就不会抛出任何错误。
<html>
<head>
<title>Scrolling Into View</title>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<style>
div.scroll { height: 6em; width: 20em; overflow: auto; }
thead th { position: sticky; top: -1px; background: #fff; }
.up, .down { cursor: pointer; }
.up:hover, .down:hover { color: blue; text-decoration:underline; }
</style>
</head>
<body>
<div class='scroll'>
<table border='1'>
<thead>
<tr>
<th>Review</th>
<th>Data</th>
</tr>
</thead>
<tbody>
<tr id='row_1'>
<th></th>
<td>Row 1 (OK)</td>
</tr>
<tr id='row_2'>
<th></th>
<td>Row 2 (OK)</td>
</tr>
<tr id='row_3'>
<th id='jump_1'><span class='up'>UP</span> <span class='down'>DN</span></th>
<td>Row 3 (REVIEW)</td>
</tr>
<tr id='row_4'>
<th></th>
<td>Row 4 (OK)</td>
</tr>
<tr id='row_5'>
<th id='jump_2'><span class='up'>UP</span> <span class='down'>DN</span></th>
<td>Row 5 (REVIEW)</td>
</tr>
<tr id='row_6'>
<th></th>
<td>Row 6 (OK)</td>
</tr>
<tr id='row_7'>
<th></th>
<td>Row 7 (OK)</td>
</tr>
<tr id='row_8'>
<th id='jump_3'><span class='up'>UP</span> <span class='down'>DN</span></th>
<td>Row 8 (REVIEW)</td>
</tr>
<tr id='row_9'>
<th></th>
<td>Row 9 (OK)</td>
</tr>
<tr id='row_10'>
<th></th>
<td>Row 10 (OK)</td>
</tr>
</tbody>
</table>
</div>
<script>
$(document).ready( function() {
$('.up').on('click', function() {
var id = parseInt($(this).parent().attr('id').split('_')[1]);
if (id>1) {
var row_id = $('#jump_' + (id - 1)).parent().attr('id').split('_')[1];
document.getElementById('row_' + (row_id-1)).scrollIntoView({behavior: 'smooth', block: 'start'});
} else {
alert('At first');
}
});
$('.down').on('click', function() {
var id = parseInt($(this).parent().attr('id').split('_')[1]);
if ($('#jump_' + (id + 1)).length) {
var row_id = $('#jump_' + (id + 1)).parent().attr('id').split('_')[1];
document.getElementById('row_' + (row_id-1)).scrollIntoView({behavior: 'smooth', block: 'start'});
} else {
alert('At last');
}
});
});
</script>
</body>
</html>
基于之前的答案,我在一个Angular5项目中这样做。
开始:
// el.scrollIntoView(true);
el.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
window.scrollBy(0, -10);
但这样会产生一些问题,需要为scrollBy()设置timeout,如下所示:
//window.scrollBy(0,-10);
setTimeout(() => {
window.scrollBy(0,-10)
}, 500);
它在MSIE11和Chrome 68+中工作完美。我没有在FF测试过。500毫秒是我敢说的最短延迟。向下走有时会失败,因为平滑的滚动还没有完成。根据您自己的项目进行调整。
+1到Fred727为这个简单而有效的解决方案。
我试着使用上面的一些答案,但滚动不起作用。经过一番研究,我注意到滚动位置实际上非常奇怪(甚至是负值),这是由Angular在路由器出口中渲染页面的方式引起的。
我的解决方案是从页面顶部开始计算元素的滚动位置。我在模板的开头放置了一个id为start-of-page的元素,通过减去目标片段位置来获得滚动量。
ngAfterViewInit(): void {
this.route.fragment.subscribe(fragment => {
try {
// @ts-ignore
// document.querySelector('#hero').scrollIntoView({behavior:smooth, block: "start", inline: "start"});
// @ts-ignore
// document.querySelector('#' + fragment).scrollIntoView({behavior:smooth, block: "start", inline: "start"});
this._scrollTo('#' + fragment,0);
} catch (e) { };
});
}
private _scrollTo(selector: any, yOffset = 0){
const base = document.querySelector('#start-of-page');
const el = document.querySelector(selector);
// @ts-ignore
const y = el.getBoundingClientRect().top - base.getBoundingClientRect().top;
window.scrollTo({top: y, behavior: 'smooth'});
}