我有一个简单的页面,我将在右侧放置一个大表格,在左侧创建一个导航菜单,使用户可以跳至该大表格的各个部分(这也可用于大型文章-现在为了模拟尺寸,我在CSS中添加了一个较大的底部填充)。右栏的样式已设置为适合使用高度:100vh的窗口的高度。
当单击右侧的链接并且节offsetTop
大于其父项的scrollTop
时,滚动是平滑的。我使用JavaScript setTimeout
,并使用循环设置超时的时间间隔,这太棒了!但是,如果我想向上滚动,那是该节的offsetTop小于其父级的scrollTop
,我会遇到问题-它变硬,缓慢且无法真正工作...我已经看了太久了因此,如果有人可以帮助我,我将非常感激。这是我的JavaScript函数
function scrollToAchor(where, event) {
event.stopPropagation();
var element = document.querySelector('.aims-form__form').querySelector('a[name="' + where + '"]');
var to = element.offsetTop - 30;
var from = document.querySelector('.aims-form__form').scrollTop
let timeOut = 0;
if(to >= from) {
for(let i = from; i <= to; i+=5) {
// this works and is great!!!
setTimeout(function () {
document.querySelector('.aims-form__form').scrollTop = i;
}, i/2);
}
} else {
for(let k = from; k >= to; k-=5) {
// I need to set the timeout Interval so the animation is smooth but it is really slow
// with the above setInterval above we are counting up... How do I get this smooth
timeOut = timeOut + (to + 15) / 2;
setTimeout(function () {
document.querySelector('.aims-form__form').scrollTop = i;
}, timeOut);
}
}
}
这不应该使我陷入困境,但是我无法摆脱困境,现在我有一个精神障碍。要更好地理解滚动功能,这里是HTML,但是要获得完整图片(包括必要的CSS),这里是完整https://jsbin.com/nidevaj/edit?html,css,js,output
的jsbin <div class="aims-form">
<div class="aims-form__navigation">
<ul>
<li>
<a onClick="scrollToAchor('section1', event)" class="aims-form__anchor">Section 1</a>
</li>
<li>
<a onClick="scrollToAchor('section2', event)" class="aims-form__anchor">Section 2</a>
</li>
<li>
<a onClick="scrollToAchor('section3', event)" class="aims-form__anchor">Section 3</a>
</li>
<li>
<a onClick="scrollToAchor('section4', event)" class="aims-form__anchor">Section 4</a>
</li>
</ul>
</div>
<div class="aims-form__form">
<section>
<a name="section1"></a>
Section 1
<br>
... content lots of content
</section>
<section>
<a name="section2"></a>
Section 2
<br>
... content lots of content
</section>
<section>
<a name="section3"></a>
Section 3
<br>
... content lots of content
</section>
<section>
<a name="section4"></a>
Section 4
<br>
... content lots of content
</section>
</div>
</div>
答案 0 :(得分:1)
您可以将CSS属性scroll-behavior
设置为smooth
(大多数现代浏览器都支持),从而无需使用Javascript。只需给锚标签添加href
中的#
,再加上锚标签的name
即可滚动到正常滚动,除了更平滑之外。
section{
margin: 500px 0px;
}
html, body{
scroll-behavior: smooth;
}
<div class="aims-form">
<div class="aims-form__navigation">
<ul>
<li>
<a href="#section1">Section 1</a>
</li>
<li>
<a href="#section2">Section 2</a>
</li>
<li>
<a href="#section3">Section 3</a>
</li>
<li>
<a href="#section4">Section 4</a>
</li>
</ul>
</div>
<div class="aims-form__form">
<section>
<a name="section1"></a>
Section 1
<br>
... content lots of content
</section>
<section>
<a name="section2"></a>
Section 2
<br>
... content lots of content
</section>
<section>
<a name="section3"></a>
Section 3
<br>
... content lots of content
</section>
<section>
<a name="section4"></a>
Section 4
<br>
... content lots of content
</section>
</div>
</div>
如果要使用Javascript,可以将for
和window.scrollTo
以及setTimeout
与setInterval
循环一起使用,以实现平滑滚动。我已经为此编写了一个函数。要滚动到某个元素,请提供元素的offsetTop
作为pos
参数。
function scrollToSmoothly(pos, time) {
/*Time is only applicable for scrolling upwards*/
/*Code written by hev1*/
/*pos is the y-position to scroll to (in pixels)*/
if (isNaN(pos)) {
throw "Position must be a number";
}
if (pos < 0) {
throw "Position can not be negative";
}
var currentPos = window.scrollY || window.screenTop;
if (currentPos < pos) {
var t = 10;
for (let i = currentPos; i <= pos; i += 10) {
t += 10;
setTimeout(function() {
window.scrollTo(0, i);
}, t / 2);
}
} else {
time = time || 2;
var i = currentPos;
var x;
x = setInterval(function() {
window.scrollTo(0, i);
i -= 10;
if (i <= pos) {
clearInterval(x);
}
}, time);
}
}
section{
margin: 500px 0px;
}
<div class="aims-form">
<div class="aims-form__navigation">
<ul>
<li>
<a onClick="scrollToAchor('section1', event)" class="aims-form__anchor">Section 1</a>
</li>
<li>
<a onClick="scrollToAchor('section2', event)" class="aims-form__anchor">Section 2</a>
</li>
<li>
<a onClick="scrollToAchor('section3', event)" class="aims-form__anchor">Section 3</a>
</li>
<li>
<a onClick="scrollToAchor('section4', event)" class="aims-form__anchor">Section 4</a>
</li>
</ul>
</div>
<div class="aims-form__form">
<section>
<a name="section1"></a>
Section 1
<br>
... content lots of content
</section>
<section>
<a name="section2"></a>
Section 2
<br>
... content lots of content
</section>
<section>
<a name="section3"></a>
Section 3
<br>
... content lots of content
</section>
<section>
<a name="section4"></a>
Section 4
<br>
... content lots of content
<button onClick="scrollToTop()">
Back To Top
</button>
</section>
</div>
</div>
<script>
function scrollToSmoothly(pos, time) {
/*Time is only applicable for scrolling upwards*/
/*Code written by hev1*/
/*pos is the y-position to scroll to (in pixels)*/
if (isNaN(pos)) {
throw "Position must be a number";
}
if (pos < 0) {
throw "Position can not be negative";
}
var currentPos = window.scrollY || window.screenTop;
if (currentPos < pos) {
var t = 10;
for (let i = currentPos; i <= pos; i += 10) {
t += 10;
setTimeout(function() {
window.scrollTo(0, i);
}, t / 2);
}
} else {
time = time || 2;
var i = currentPos;
var x;
x = setInterval(function() {
window.scrollTo(0, i);
i -= 10;
if (i <= pos) {
clearInterval(x);
}
}, time);
}
}
function scrollToAchor(where, event) {
event.stopPropagation();
var element = document.querySelector('.aims-form__form').querySelector('a[name="' + where + '"]');
scrollToSmoothly(element.offsetTop);
}
function scrollToTop(){
scrollToSmoothly(0);
}
</script>
如果要使div
的内容平滑滚动,可以使用上述功能,将window.scrollTo
替换为elem.scrollTop
,然后将元素的offsetTop
传入pos
滚动到元素。
section{
margin: 500px 0px;
}
<div style="border: 1px solid black; margin: auto; height: 250px; width: 50%; overflow-y: auto;" id="parent">
<div class="aims-form">
<div class="aims-form__navigation">
<ul>
<li>
<a onClick="scrollToAnchor('section1', event)" class="aims-form__anchor">Section 1</a>
</li>
<li>
<a onClick="scrollToAnchor('section2', event)" class="aims-form__anchor">Section 2</a>
</li>
<li>
<a onClick="scrollToAnchor('section3', event)" class="aims-form__anchor">Section 3</a>
</li>
<li>
<a onClick="scrollToAnchor('section4', event)" class="aims-form__anchor">Section 4</a>
</li>
</ul>
</div>
<div class="aims-form__form">
<section>
<a name="section1"></a>
Section 1
<br>
... content lots of content
</section>
<section>
<a name="section2"></a>
Section 2
<br>
... content lots of content
</section>
<section>
<a name="section3"></a>
Section 3
<br>
... content lots of content
</section>
<section>
<a name="section4"></a>
Section 4
<br>
... content lots of content
<p/>
<button onClick="scrollToTopOfDiv()">
Back To Top
</button>
</section>
</div>
</div>
</div>
<script>
function scrollToSmoothlyInsideElement(elem, pos, time) {
/*Time is only applicable for scrolling upwards*/
/*Code written by hev1*/
/*pos is the y-position to scroll to (in pixels)*/
if (isNaN(pos)) {
throw "Position must be a number";
}
if (pos < 0) {
throw "Position can not be negative";
}
var currentPos = elem.scrollTop;
if (currentPos < pos) {
var t = 10;
for (let i = currentPos; i <= pos; i += 10) {
t += 10;
setTimeout(function() {
elem.scrollTop = i;
}, t / 2);
}
} else {
time = time || 2;
var i = currentPos;
var x;
x = setInterval(function() {
elem.scrollTop = i;
i -= 10;
if (i <= pos) {
clearInterval(x);
}
}, time);
}
}
function scrollToAnchor(where, event){
event.stopPropagation();
var element = document.querySelector('.aims-form__form').querySelector('a[name="' + where + '"]');
var parent = document.querySelector('#parent');
scrollToSmoothlyInsideElement(parent, element.offsetTop);
}
function scrollToTopOfDiv(){
var elem = document.querySelector('#parent');
scrollToSmoothlyInsideElement(elem, 0);
}
</script>