在iOS Safari上,window.scrollTo在方向改变后不起作用

时间:2016-07-01 09:27:19

标签: javascript ios mobile-safari

简而言之:

在iOS Safari中,如果从orientationchange事件处理程序调用,window.scrollTo方法不会执行任何操作。在方向更改后修改滚动位置之前,似乎必须经过一定的时间(500-1000ms)。

是否有一种解决方法可以立即更改滚动位置,并避免在用户在方向更改后看到旧滚动位置时出现问题?

详细问题说明:

我需要为移动浏览器实现以下功能:

当用户切换到横向模式时,他应该会看到全屏视频。当他切换回肖像时,他应该被送回到他离开的地方。

第二部分是问题所在。如果你来回切换方向,iOS和Android都会保持滚动位置,但前提是你不滚动屏幕而不对DOM进行任何调整。因此,如果您只是从纵向切换到横向和背面,一切都按预期工作。如果您从纵向切换到横向,即使按1像素调整滚动位置或对DOM进行任何更改,您将返回到不同的滚动位置。

因此,当用户返回纵向时,我尝试以实际方式恢复滚动位置。这是我使用的简化代码:

    var scrollPosition;
    var savedScrollPosition;

    window.addEventListener('scroll', function() {
        scrollPosition = window.scrollY;
    });

    window.addEventListener('orientationchange', function(event) {
        if (Math.abs(window.orientation) === 90) {
            // This line will correctly save last scroll position for portrait orientation
            savedScrollPosition = scrollPosition;
        } else {
            // This line will correctly try to restore previously saved scroll position
            window.scrollTo(0, savedScrollPosition);
        }
    });

这适用于Android,但在iOS上它并不适用。问题是,window.scrollTo似乎没有做任何事情,直到定向更改过去后的某个时间。

所以,如果我改变

window.scrollTo(0, savedScrollPosition);

setTimeout(function() {
    window.scrollTo(0, savedScrollPosition);
}, 1000);

它适用于iOS,但用户可能会在一段时间内看到页面的错误部分,从而导致用户体验不佳。

我希望有人知道如何在orientationchage事件发生后立即更改iOS上的滚动位置。

谢谢。

1 个答案:

答案 0 :(得分:3)

最后,我被迫使用以下代码:

var scrollPosition;
var savedScrollPosition;

window.addEventListener('scroll', function() {
    scrollPosition = window.scrollY;
});

window.addEventListener('orientationchange', function(event) {
    if (Math.abs(window.orientation) === 90) {
        savedScrollPosition = scrollPosition;
    } else {
        if (isIOS()) {
            var retryScroll = setInterval(function () {
                if (window.scrollX === 0 && window.scrollY == savedScrollPosition) {
                    clearInterval(retryScroll);
                } else {
                    window.scrollTo(0, savedScrollPosition);
                }
            }, 10 );
        } else {
            window.scrollTo(0, savedScrollPosition);
        }
    }
});

用户会看到一个小的视觉故障,但它仍然是最好的解决方案。