我一直在寻找一个很好的解决方案,只需点击一下,然后以动画的方式将div
(当然可以滚动)滚动到顶部。我遇到了this(#2解决方案),看起来非常不错,但它滚动整个窗口而不是特定的div
。
我稍微修改了这个函数,以便它可以滚动容器而不是整个窗口。这是我的版本:
function scrollContainerToTop(scrollDuration, container_id) {
const container = document.getElementById(container_id),
scrollHeight = container.scrollTop,
scrollStep = Math.PI / (scrollDuration / 15),
cosParameter = scrollHeight / 2;
var scrollCount = 0,
scrollMargin,
scrollInterval = setInterval(function () {
if (container.scrollTop != 0) {
scrollCount = scrollCount + 1;
scrollMargin = cosParameter - cosParameter * Math.cos(scrollCount * scrollStep);
container.scrollTop = (scrollHeight - scrollMargin);
} else clearInterval(scrollInterval);
}, 15);
}
here是一个功能性示例,您可以尝试:将所有" Hello" s滚动到底部,然后单击按钮以使用javascript向上滚动它。
所以我的问题是,它不是只是向上滚动,而是快速向上和向下滚动两到三次然后才能在顶部向上滚动。但是,如果你以更大的延迟(比如说300毫秒)调用滚动功能,那么一切都很好。我尝试使用Safari,Chrome和较旧版本的Firefox,并且每个版本都会产生相同的错误结果。
那么,如果我提供更快的滚动时间,为什么这个功能会出现故障呢?
答案 0 :(得分:0)
快速检查调试器(使用精心放置的console.log)将回答以下问题:
function scrollContainerToTop(scrollDuration, container_id) {
const container = document.getElementById(container_id),
scrollHeight = container.scrollTop,
scrollStep = Math.PI / (scrollDuration / 15),
cosParameter = scrollHeight / 2;
var scrollCount = 0,
scrollMargin,
scrollInterval = setInterval(function () {
if (container.scrollTop != 0) {
scrollCount = scrollCount + 1;
scrollMargin = cosParameter - cosParameter * Math.cos(scrollCount * scrollStep);
container.scrollTop = (scrollHeight - scrollMargin);
// debug here:
console.log( 'container.scrollTop = ' + container.scrollTop );
} else clearInterval(scrollInterval);
}, 150);
}
结果:
container.scrollTop = 554
container.scrollTop = 465
container.scrollTop = 338
container.scrollTop = 202
container.scrollTop = 85
container.scrollTop = 14
container.scrollTop = 3
container.scrollTop = 55
container.scrollTop = 159
container.scrollTop = 293
container.scrollTop = 426
container.scrollTop = 530
container.scrollTop = 582
container.scrollTop = 571
container.scrollTop = 500
container.scrollTop = 383
container.scrollTop = 247
container.scrollTop = 120
container.scrollTop = 31
container.scrollTop = 0
有关更完整的解释:
当你未能达到0时,下一次迭代实际上会产生一个负scrollMargin
(因为那是how cosine works)。迭代继续前后,直到你最终达到0。
看看当我们输出变量的实际值时会发生什么:
console.log( 'scrollMargin = ' + cosParameter + ' - ' + cosParameter + ' * ' + Math.cos(scrollCount * scrollStep) );
scrollMargin = 293 - 293 * 0.8910065241883679
scrollMargin = 293 - 293 * 0.5877852522924731
scrollMargin = 293 - 293 * 0.15643446504023092
scrollMargin = 293 - 293 * -0.30901699437494734
scrollMargin = 293 - 293 * -0.7071067811865475
scrollMargin = 293 - 293 * -0.9510565162951535
scrollMargin = 293 - 293 * -0.9876883405951378
scrollMargin = 293 - 293 * -0.8090169943749475
scrollMargin = 293 - 293 * -0.4539904997395469
scrollMargin = 293 - 293 * -1.8369701987210297e-16
scrollMargin = 293 - 293 * 0.45399049973954664
scrollMargin = 293 - 293 * 0.8090169943749472
scrollMargin = 293 - 293 * 0.9876883405951377
scrollMargin = 293 - 293 * 0.9510565162951536
scrollMargin = 293 - 293 * 0.7071067811865477
scrollMargin = 293 - 293 * 0.30901699437494773
scrollMargin = 293 - 293 * -0.15643446504022968
scrollMargin = 293 - 293 * -0.5877852522924729
scrollMargin = 293 - 293 * -0.8910065241883681
scrollMargin = 293 - 293 * -1
一种解决方案是简单地检查生成的container.scrollTop。如果您在scrollMargin中,那么请继续并完成滚动:
if (container.scrollTop < scrollMargin) container.scrollTop = 0;