今天我經歷了一次非常尷尬的事件。像往常一樣,我使用 window.innerWidth 來測量瀏覽器的寬度,並在小於768px的情況下讓 isMobile = true。我也進行了徹底的測試。在iPhone、Galaxy等各種設備上,從Safari、Chrome到Brave瀏覽器都運行過,確認沒有異常。

然而…

一位朋友突然告訴我我的網頁應用在Galaxy的 三星瀏覽器 中看起來奇怪。"不會吧?"我心想,但親自測試後發現 在三星瀏覽器下,即使是在移動環境中 window.innerWidth < 768 也顯示為false,真是個奇怪的情況。

我實在無法理解。只有在三星瀏覽器中才出現這種情況也很奇怪, 我發現在PC的Chrome和Firefox瀏覽器的開發者模式下檢查移動屏幕時也返回false

Developer testing a website on a smartphone


為問題解決做的各種嘗試

我立即測試了其他方法。

1. window.innerWidth

const isMobile = window.innerWidth < 768;

✅ 在普通的瀏覽器中正常運行
在三星瀏覽器和PC的Chrome/Firefox開發者模式下返回false(失敗)

2. 增加 document.documentElement.clientWidth

const isMobile = (window.innerWidth || document.documentElement.clientWidth) < 768;

✅ 在邏輯上更安全的代碼
在三星瀏覽器及開發者模式下仍然返回false(失敗)

3. 使用 window.matchMedia('(max-width: 767px)')

const isMobile = window.matchMedia('(max-width: 767px)').matches;

在所有瀏覽器中正常運行!(成功 🎉)

看到這結果,我得出結論。
未來判斷是否為移動設備時,應該使用 window.matchMedia


為什麼會發生這樣的事?

老實說,除非直接查看瀏覽器的內部源代碼,不然很難確定準確的原因。但可以進行一些猜測。

  1. 三星瀏覽器的渲染方式差異
    三星瀏覽器雖然基於Chromium,但進行了許多自定義優化。在這過程中, window.innerWidth 的值可能會與一般的移動瀏覽器行為不同。

  2. PC的Chrome & Firefox開發者模式發生問題的原因
    當在開發者模式下啟用"模擬移動設備"功能時,瀏覽器不僅調整屏幕大小,還會內部改變多個設置。然而,並不是所有環境都能100%完美地模擬實際的移動設備。開發者模式下 window.innerWidth 的值與實際設備的行為不同也是可能的原因。

  3. 滾動條包含情況的差異
    window.innerWidth 包含視口的寬度,而 document.documentElement.clientWidth 返回的是不包括滾動條的實際內容寬度。
    隱約懷疑三星瀏覽器可能在內部以不同的方式處理滾動條,但這一假設無法解釋所有的現象。

總結來說…


未來檢查是否為移動設備時,一定要使用 matchMedia

通過這次經歷,我意識到像 window.innerWidth 的方法不可靠。
未來判斷移動環境時,安全的方法是使用下面的 matchMedia

const isMobile = window.matchMedia('(max-width: 767px)').matches;

📌 使用這種方法可以
✅ 在所有瀏覽器中正常運行。
✅ 在開發者模式下也能獲得一致的結果。
✅ 在三星瀏覽器等特殊環境中也能正常運行。

有時,這些意想不到的bug的經歷是成為優秀開發者過程中的一部分。無論如何,今天因為 三星瀏覽器而意識到需要使用 matchMedia 😆