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

时间:2013-06-20 11:45:41

标签: 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);
  4. 输出为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());
    

    VS

    var $w = $(window); 
    $w.scrollTop(100); 
    window.setTimeout(function() {
        console.log($w.scrollTop())
    }, 1);
    

    此行为是否正常或是否为错误?怎么处理? (现在我修改了$.fn.scrollTop以返回$.Deferred而不是链接并立即在除Safari之外的所有浏览器的主线程中解析它。

3 个答案:

答案 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}}