window.scrollTo在Safari中异步工作吗?

ica*_*oli 10 javascript safari scroll

最近我发现在Safari(6.0.5(8536.30.1),MacOS 10.8.4)中的window.scrollTo行为非常奇怪(在我看来).它似乎异步工作.

我的任务听起来像:

  • 使一些绝对定位的div固定(固定)
  • 做一些页面滚动
  • 使之前修改过的div绝对定位(取消固定)

因此,要取消固定此div,我必须在滚动修改完成后执行unpin例程.在这里,我遇到了这个问题.我检查的每个浏览器都能正确执行,除了Safari.

重现步骤:

  1. 在Safari中打开任何网页,并确保它至少可滚动100px,并且它的初始滚动偏移为0
  2. 在开发工具中打开js控制台
  3. 执行: window.scrollTo(0, 100); console.log(document.body.scrollTop);

输出为0.但是当我将此代码更改window.scrollTo(0, 100); window.setTimeout(function() {console.log(document.body.scrollTop)}, 1);为输出为100时,正如预期的那样.

以下是我测试的所有其他浏览器(它工作正常):

  • Chrome 27.0.1453.110(MacOS 10.8.4)
  • Firefox 21.0(MacOS 10.8.4)
  • Opera 12.15 b1748(MacOS 10.8.4)
  • IE 8.0.7601.17514(Win7)

好吧,只要我的代码示例不是跨浏览器,就可以使用jQuery在任何网页上检查此行为更容易:

var $w = $(window); 
$w.scrollTop(100); 
console.log($w.scrollTop());
Run Code Online (Sandbox Code Playgroud)

VS

var $w = $(window); 
$w.scrollTop(100); 
window.setTimeout(function() {
    console.log($w.scrollTop())
}, 1);
Run Code Online (Sandbox Code Playgroud)

这种行为是好的还是一个bug?怎么处理?(现在我修改$.fn.scrollTop为返回$.Deferred而不是链接并立即在除Safari之外的所有浏览器的主线程中解析它).

Ala*_*Tam 1

实际上,我只是尝试并未能重现您的问题,即使使用 Safari 6.0.5(在 Lion 上,即 OS X 10.7)。

您可以使用https://www.browserstack.com/screenshots运行此jsfiddle,以确认它适用于所有 Safari 版本(5.1、6.0、6.1、7、8)。

事实上,规范说并且我引用:

当用户代理要执行滚动框 box 的平滑滚动来定位时,它必须在用户代理定义的时间内以用户代理定义的方式更新框的滚动位置。当滚动完成后,box的滚动位置必须是position。滚动也可以通过算法或用户来中止。

除非我读错了,否则 Safari 有权在滚动动画时为您提供旧值(或者实际上任何东西)。因此,setTimeout如果浏览器想要将其发挥到极致,您的方法甚至可能无法正常工作。