最近我发现在Safari(6.0.5(8536.30.1),MacOS 10.8.4)中的window.scrollTo行为非常奇怪(在我看来)。它似乎异步工作。
我的任务听起来像是:
因此,为了取消固定此div,我必须在滚动修改完成后执行unpin例程。在这里,我遇到了这个问题。我检查的每个浏览器都能正确执行,除了Safari。
重现的步骤:
window.scrollTo(0, 100); console.log(document.body.scrollTop);
输出为0.但是当我将此代码更改为window.scrollTo(0, 100); window.setTimeout(function() {console.log(document.body.scrollTop)}, 1);
时,输出为100,正如预期的那样。
以下是我测试过的所有其他浏览器(工作正常):
好吧,只要我的代码示例不是跨浏览器,就可以更容易地在使用jQuery的任何网页上检查此行为:
var $w = $(window);
$w.scrollTop(100);
console.log($w.scrollTop());
VS
var $w = $(window);
$w.scrollTop(100);
window.setTimeout(function() {
console.log($w.scrollTop())
}, 1);
此行为是否正常或是否为错误?怎么处理? (现在我修改了$.fn.scrollTop
以返回$.Deferred
而不是链接并立即在除Safari之外的所有浏览器的主线程中解析它。
答案 0 :(得分:1)
即使使用Safari 6.0.5(在Lion上,即OS X 10.7),我实际上只是尝试并且无法重现您的问题。
您可以使用jsfiddle运行此https://www.browserstack.com/screenshots,以确认它适用于所有Safari版本(5.1,6.0,6.1,7,8)。
确实spec说了,我引用了:
当用户代理要执行滚动框框的平滑滚动以进行定位时,它必须在用户代理定义的时间内在用户代理定义的时间内更新框的滚动位置。滚动完成后,框的滚动位置必须是位置。滚动也可以通过算法或用户中止。
除非我读错了,否则Safari有权在给动画滚动动画时给你旧值(或者实际上是任何东西)。因此,如果浏览器想要将其发挥到极致,那么setTimeout
方法甚至可能无法正常工作。
答案 1 :(得分:0)
在requestAnimationFrame
中设置滚动顶部实际上解决了我在浏览器中的问题。
答案 2 :(得分:0)
JavaScript滚动功能通常可以同步工作。我在scrollBy()
上遇到了类似的问题,我注意到它异步运行,导致我的函数崩溃。问题在于浏览器具有默认的CSS属性scroll-behavior: smooth
,这导致滚动功能与requestAnimationFrame()
自动运行,而scroll-behavior
异步运行。确保unset
的值为* {
scroll-behavior: unset
}
或像这样在CSS中全局覆盖它:
{{1}}