我有一个页面,其中一个滚动条包含从数据库动态生成的带有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个像素太高了。
有人知道怎么解决吗?
用绝对法定位锚
另一种方法是将锚定位在页面上想要的位置,而不是依赖于按偏移量滚动。我发现它可以更好地控制每个元素(例如。如果你想对某些元素有不同的偏移量),并且可能对浏览器API的变化/差异更有抵抗力。
<div id="title-element" style="position: relative;">
<div id="anchor-name" style="position: absolute; top: -100px; left: 0"></div>
</div>
现在相对于元素的偏移量被指定为-100px。创建一个函数来创建这个锚,以便代码重用,或者如果你正在使用一个现代的JS框架,比如React,通过创建一个渲染锚的组件来实现,并传入锚的名称和每个元素的对齐方式,这些元素可能相同,也可能不相同。
然后使用:
const element = document.getElementById('anchor-name')
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
平滑滚动,偏移量为100px。
基于之前的答案,我在一个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为这个简单而有效的解决方案。
用绝对法定位锚
另一种方法是将锚定位在页面上想要的位置,而不是依赖于按偏移量滚动。我发现它可以更好地控制每个元素(例如。如果你想对某些元素有不同的偏移量),并且可能对浏览器API的变化/差异更有抵抗力。
<div id="title-element" style="position: relative;">
<div id="anchor-name" style="position: absolute; top: -100px; left: 0"></div>
</div>
现在相对于元素的偏移量被指定为-100px。创建一个函数来创建这个锚,以便代码重用,或者如果你正在使用一个现代的JS框架,比如React,通过创建一个渲染锚的组件来实现,并传入锚的名称和每个元素的对齐方式,这些元素可能相同,也可能不相同。
然后使用:
const element = document.getElementById('anchor-name')
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
平滑滚动,偏移量为100px。
这是我的两分钱。
我也有scrollIntoView滚动过去元素一点的问题,所以我创建了一个脚本(本机javascript),将一个元素前置到目的地,将它定位到顶部的css和滚动到那一个。滚动后,再次删除创建的元素。
HTML:
//anchor tag that appears multiple times on the page
<a href="#" class="anchors__link js-anchor" data-target="schedule">
<div class="anchors__text">
Scroll to the schedule
</div>
</a>
//The node we want to scroll to, somewhere on the page
<div id="schedule">
//html
</div>
Javascript文件:
(() => {
'use strict';
const anchors = document.querySelectorAll('.js-anchor');
//if there are no anchors found, don't run the script
if (!anchors || anchors.length <= 0) return;
anchors.forEach(anchor => {
//get the target from the data attribute
const target = anchor.dataset.target;
//search for the destination element to scroll to
const destination = document.querySelector(`#${target}`);
//if the destination element does not exist, don't run the rest of the code
if (!destination) return;
anchor.addEventListener('click', (e) => {
e.preventDefault();
//create a new element and add the `anchors__generated` class to it
const generatedAnchor = document.createElement('div');
generatedAnchor.classList.add('anchors__generated');
//get the first child of the destination element, insert the generated element before it. (so the scrollIntoView function scrolls to the top of the element instead of the bottom)
const firstChild = destination.firstChild;
destination.insertBefore(generatedAnchor, firstChild);
//finally fire the scrollIntoView function and make it animate "smoothly"
generatedAnchor.scrollIntoView({
behavior: "smooth",
block: "start",
inline: "start"
});
//remove the generated element after 1ms. We need the timeout so the scrollIntoView function has something to scroll to.
setTimeout(() => {
destination.removeChild(generatedAnchor);
}, 1);
})
})
})();
CSS:
.anchors__generated {
position: relative;
top: -100px;
}
希望这能帮助到大家!
对于表行中的元素,使用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>