2016-07-01 131 views
3

工作後,簡而言之:在iOS上的Safari,window.scrollTo不取向變化

在iOS的Safari瀏覽器,如果從orientationChange事件處理函數中調用window.scrollTo方法不能做任何事情。在取向改變之後,您可以修改滾動位置之前,似乎必須經過一段時間(500-1000毫秒)。

是否有解決方法立即更改滾動位置,並避免在用戶在方向更改後可以看到舊滾動位置一段時間時的問題?

詳細問題描述:

我需要實現以下功能的移動瀏覽器:

當用戶切換到橫屏模式,他應該看到全屏的視頻。當他切換回肖像時,他應該返回到他離開的完全相同的地方。

第二部分是問題。如果您來回切換方向,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,但用戶可以看到片刻頁面的錯誤部分,從而導致較差的用戶體驗。

我希望有人知道在方向切換事件後立即在iOS上更改滾動位置的方法。

謝謝。

+0

延遲時間延遲會發生什麼?說'100' – Rayon

+0

@Rayon沒什麼。 Window保持它通常保持的位置,而不需要任何scrollTo調用。大約500毫秒是當你得到50/50實際改變卷軸的機會時。當然,有一種解決方案可以通過設置10ms的間隔加速結果,調用scrollTo,然後檢查window.scrollY是否已經改變。但是無論間隔時間有多小,用戶一會兒仍然會看到無效位置。 – Alexey

+0

您是否正在運行最新的iOS?我依稀記得有一些方向性問題被引入,然後在相對較新的版本中得到修復,但我不知道它們是否包含了您正在經歷的內容。 – DBS

回答

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); 
     } 
    } 
}); 

用戶將看到一個小的視覺干擾,但它仍然是最好的解決辦法。