跳到主要內容
前端開發

screen.orientation:現在判斷與鎖定螢幕方向的做法

整理現在 JavaScript 判斷螢幕方向的方式,包括 screen.orientation、change 事件與 lock(),並說明 RWD 使用 matchMedia 或 CSS orientation 會更適合。

W

早年判斷與鎖定螢幕方向時,常看到:

window.orientation

或各家瀏覽器自己實作的:

screen.lockOrientation()

現在如果真的需要知道裝置目前的螢幕方向,可以使用標準的 Screen Orientation API。

取得目前方向

console.log(screen.orientation.type)
console.log(screen.orientation.angle)

type 可能會得到:

portrait-primary
portrait-secondary
landscape-primary
landscape-secondary

例如:

if (screen.orientation.type.startsWith('portrait')) {
  console.log('目前是直向')
}

angle 則可以取得目前旋轉的角度:

console.log(screen.orientation.angle)
// 0、90、180、270

監聽方向改變

如果使用者旋轉手機,可以監聽 change:

screen.orientation.addEventListener('change', () => {
  console.log(
    '目前方向:',
    screen.orientation.type
  )
})

這比以前自己監聽 resize 或判斷 window.orientation 清楚很多。

如果只是做 RWD

如果只是想知道:

現在畫面是直向還是橫向?

其實不一定需要 screen.orientation。

CSS 直接使用:

@media (orientation: portrait) {
  /* 直向 */
}

@media (orientation: landscape) {
  /* 橫向 */
}

JavaScript 也可以:

const isPortrait = window.matchMedia(
  '(orientation: portrait)'
).matches

可以簡單區分:

RWD / 版面切換
→ CSS @media
→ matchMedia()

需要取得裝置方向、角度
→ screen.orientation

鎖定螢幕方向

Screen Orientation API 也提供 lock():

try {
  await screen.orientation.lock('landscape')
} catch (error) {
  console.log('無法鎖定螢幕方向')
}

例如:

await screen.orientation.lock('portrait')

或:

await screen.orientation.lock('landscape')

但要注意:

lock() 的瀏覽器支援與使用限制,比單純讀取 screen.orientation 多很多。

有些瀏覽器需要先進入全螢幕模式,才能鎖定方向:

async function enterLandscapeMode(element) {
  await element.requestFullscreen()

  await screen.orientation.lock(
    'landscape'
  )
}

所以一般網頁不要假設:

screen.orientation.lock()

一定能成功。

實際使用時要用 try...catch 處理失敗。

解除鎖定

如果之前成功鎖定方向,可以使用:

screen.orientation.unlock()

讓裝置恢復正常的自動旋轉行為。

什麼情況才需要 lock()?

一般網站其實很少需要強制鎖定方向。

比較常見的是:

Web 遊戲
全螢幕播放器
電子看板
需要固定橫向操作的工具
PWA

普通的 RWD 網頁通常只需要:

@media (orientation: portrait) {}

不用主動去鎖使用者的螢幕方向。

舊寫法與現在的差異

想做的事舊寫法現在
取得裝置方向window.orientationscreen.orientation.type
取得旋轉角度window.orientationscreen.orientation.angle
監聽方向改變orientationchange / resizescreen.orientation 的 change
RWD 判斷CSS media query一樣使用 CSS media query
JavaScript 判斷版面方向自己計算寬高matchMedia()
鎖定方向各家非標準 APIscreen.orientation.lock()

小結

如果只是做 RWD:

@media (orientation: portrait) {
}

就夠了。

如果 JavaScript 需要知道目前畫面方向:

window.matchMedia(
  '(orientation: portrait)'
).matches

如果需要更完整的裝置方向資訊:

screen.orientation.type
screen.orientation.angle

真的需要鎖定方向時才使用:

await screen.orientation.lock('landscape')

而且要記得:

lock() 並不是一般網頁在所有瀏覽器都能直接使用,必須做好失敗處理。

參考資料

分享這篇