現在市面上的扁平螢幕讓網頁可視範圍越來越小,以前 4:3、16:10 等適合看網頁的尺寸已經很難看到,主流比例成為 16:9、21:9、32:9 等適合看電影或多工的用途。
為了增加網頁的可視高度,按 F11 進入全螢幕模式是常見作法。這陣子在研究如何寫自動化程式,構想是偵測到全螢幕時,將頁面上無用區塊進一步隱藏,讓可閱讀範圍增加。
原以為這是件極簡單的事,多年前寫「線上看電視」就用 Javascript 操作進入全螢幕、以及檢測當下是否為全螢幕狀態。但這次研究才發現,按 F11 進入全螢幕後,JS 是偵測不到的!如果要用 JS 繞別的路來判斷是否為全螢幕狀態,網路上幾乎找不到有效的作法。
對於這件意料之外的艱鉅任務,還好最後有找到答案,請見本篇的研究心得,以及運用這個技術,我想改善的情境為何。
(圖片出處: chatgpt.com)
一、JS 能作到的事
開始研究之前,有必要先了解 Javascript 能作到、不能作到的事。 1. 全螢幕相關操作 可參考官方文件「使用全螢幕模式」:- 可進入全螢幕模式:例如執行 document.body.requestFullscreen()
- 可離開全螢幕模式:例如執行 document.exitFullscreen()
- 可偵測全螢幕狀態:例如執行 document.addEventListener("fullscreenChange", ...) 詳細語法參考官方文件「Document: fullscreenchange event」
- 對於使用者按 F11 產生的全螢幕,無法偵測或離開全螢幕狀態
- 螢幕尺寸:執行 screen.width、screen.height
- 瀏覽器尺寸(包含網址列、書籤列..等等):執行 window.outerWidth、window.outerHeight
- 網頁可視尺寸:window.innerWidth、window.innerHeight
二、以往判斷全螢幕模式的思路
1. 網路資訊 「判斷全螢幕模式」這件事並不稀罕,所以查一下網路上都是如何解決的:- 大部分網頁提到的都是使用 JS 操作前面提過的 fullscreenchange 來偵測全螢幕狀態,但會這樣寫的人應該都不知道按 F11 的全螢幕是偵測不到的。
- 另一派的解法如同前面 stackoverflow 討論串「How to detect browser has gone to full screen」,認為 "screen.width === window.innerWidth" 的狀態就是全螢幕
- window.innerWidth 怎麼樣都不會等於 screen.width
- 瀏覽器最大化時,screen.width 等於 window.outerWidth,但兩者數值都遠低於螢幕寬度 px 值
- window.innerWidth 有時會比 window.outerWidth 還大
window.innerWidth * window.devicePixelRatio 大約等於 screen.width
這才了解 devicePixelRatio 是瀏覽器根據縮放比例而產生的數值,此數字乘上 window.innerWidth 才會是接近螢幕的寬度。
既然瀏覽器縮放會讓 devicePixelRatio 數值變動,那麼同理 window.innerWidth 也會隨之不斷變動,這也能解釋為何 innerWidth 會大於 outerWidth 了。
只不過 window.innerWidth * window.devicePixelRatio 回答了我的困惑,然而以下狀況依然得不到解答:
- screen.width 的數值不是螢幕寬度
- screen.width 與 window.outerWidth 兩者數值都遠低於螢幕寬度
三、觀察作業系統縮放比例
做完一連串實驗後,我的疑惑得到了解答: 1. 1920*1200 螢幕 為了讓螢幕文字更清楚,我的 Win10 無論是縮放比例、文字大小都經過調整,以下全螢幕狀態的測試數據來自 16:10 螢幕、1920*1200 解析度。- 縮放比例 200%、字體縮放 125%(等同於 2*1.25 = 250%)
- window.outerWidth=758、window.outerHeight=470
- screen.width=768、screen.height=480
- 縮放比例 200%、字體縮放無
- window.outerWidth=948、window.outerHeight=588
- screen.width=960、screen.height=600
- 縮放比例 150%、字體縮放無
- window.outerWidth=1264、window.outerHeight=783
- screen.width=1280、screen.height=800
- 縮放比例 100%、字體縮放無
- window.outerWidth=1894、window.outerHeight=1174
- screen.width=1920、screen.height=1200
- 作業系統的縮放比例會影響 screen.width 的值,當完全沒有縮放時,screen 長寬值就能顯示原始的 1920*1200
- 瀏覽器 outerWidth 與 outerHeight 在全螢幕下,不知為何總是比 screen 小一些,而且呈現等比例狀態
- 在作業系統無縮放時,outerWidth 與 outerHeight 減少的數值為 26*26,似乎 Chrome 瀏覽器會自動扣除 26*26 px,不知是否此數值為視窗標題高度與捲軸寬度?
- 縮放比例 100%、字體縮放無
- window.outerWidth=1896、window.outerHeight=1056
- screen.width=1920、screen.height=1080
- 當 screen 的寬高等於 window 的 outer 寬高時,一定不是全螢幕狀態
- 當 screen 的寬高大於 window 的 outer 寬高,且兩者高度差距約等於 screen 的 2.2% 時,此時有 99% 的可能性是全螢幕狀態
- 1% 的可能性是使用者自己手動拉螢幕大小,拉到接近螢幕大小,誤入此區段時,導致 JS 判斷錯誤
四、利用 CSS 判斷全螢幕狀態
可參考這個討論串「Detect fullscreen mode」,被標注正解的方法一點用也沒有,前面已經提過,但我仔細看過每個回覆後,卻發現了寶藏。 1. CSS 判斷全螢幕 其中有一樓不到 10 個推薦,卻隱藏了完美又優雅的解法,讓我十分拜服並立刻幫按推薦。 原來 CSS 的 @media 語法包含了全螢幕狀態,可參考官網文件「display-mode」,語法如下:@media all and (display-mode: fullscreen) {
/*全螢幕下的CSS樣式*/
}
如果非全螢幕狀態,則將語法改為以下:
@media not all and (display-mode: fullscreen) {
/*非全螢幕下的CSS樣式*/
}
2. JS 監控 CSS 的語法
有了 CSS 解法後,如何用 JS 來讀取 CSS 的狀態呢?可參考官網文件「matchMedia() method」,參考語法如下:
var isFullScreen = window.matchMedia("(display-mode: fullscreen)").matches;
if (isFullScreen){
// 全螢幕執行的語法
} else {
// 非全螢幕執行的語法
}
至此,優雅又簡潔的語法終於找到了!無論是否按 F11 的全螢幕狀態都能偵測出來了~
六、應用情境
那麼,我大費周章找出偵測全螢幕狀態的方法,究竟用途為何呢?簡單舉兩個目前想到的作法: 1. Google 試算表 Google 試算表的工作表區塊,在長寬比很窄的螢幕下,能看到的資料行數少的可憐,網頁超過一半的高度被這些區塊佔據了:- 瀏覽器網址列、書籤列
- 試算表標題、選單、工具圖示
- 公式列、底部工作表頁籤
更多 Javascript 相關技巧:
沒有留言:
張貼留言注意事項:
◎ 勾選「通知我」可收到後續回覆的mail!
◎ 請在相關文章留言,與文章無關的主題可至「Blogger 社團」提問。
◎ 請避免使用 Safari 瀏覽器,否則無法登入 Google 帳號留言(只能匿名留言)!
◎ 提問若無法提供足夠的資訊供判斷,可能會被無視。建議先參考這篇「Blogger 提問技巧及注意事項」。
◎ CSS 相關問題非免費諮詢,建議使用「Chrome 開發人員工具」尋找答案。
◎ 手機版相關問題請參考「Blogger 行動版範本的特質」→「三、行動版範本不一定能執行網頁版工具」;或參考「Blogger 行動版範本修改技巧 」,或本站 Blogger 行動版標籤相關文章。
◎ 非官方範本問題、或貴站為商業網站,請參考「Blogger 免費諮詢 + 付費諮詢」
◎ 若是使用官方 RWD 範本,請參考「Blogger 推出全新自適應 RWD 官方範本及佈景主題」→ 不建議對範本進行修改!
◎ 若留言要輸入語法,"<"、">"這兩個符號請用其他符號代替,否則語法會消失!
◎ 為了過濾垃圾留言,所有留言不會即時發佈,請稍待片刻。
◎ 本站「已關閉自刪留言功能」。