前言

新開的一個 tag

還沒做其他功能分類

這個用途主要是讓我常常能回顧在工作學到的東西

有時候在解 bug 或是做 feature 總會出現 「啊!原來是這樣喔!」的時刻

我也會把它記錄在 heptabase 裡面

但是光光這樣紀錄我覺得好像也沒有進入我的腦袋

所以就在這邊多做一個紀錄的過程,應該會幫助我學得更深刻

window.matchMedia

可以用這個 function 取得一個 MediaQueryList

然後用指定的 string 去讓他判斷是否存在於當前瀏覽器

然後可以從他返回的物件的 matches boolean 值判斷是否是該狀態

舉個例子:

// 檢測目前視窗大小
// 使用示例

const useMediaQuery = (query) => {
    const [matches, setMatches] = useState(window.matchMedia(query).matches);

    useEffect(() => {
        const mediaQueryList = window.matchMedia(query);
        const listener = (event) => setMatches(event.matches);

        mediaQueryList.addListener(listener);
        return () => mediaQueryList.removeListener(listener);
    }, [query]);

    return matches;
};

const MyComponent = () => {
    const isMobile = useMediaQuery('(max-width: 600px)');

    return (
        <div>
            {isMobile ? 'Mobile View' : 'Desktop View'}
        </div>
    );
};

比較常用的功能有這些:

  • PWA 模式

  • 視口監測

  • 主題偏好

  • pointer 交互

  • 畫質

主題、個人化、裝置、效能 這些相關的都可以想到這個東西來處理

手機旋轉狀態

這個其實延續到上一個 matchMedia 其中一個用法

這邊針對偵測的一個小小的點多做說明

以 react 為例

先定義初始 state

(會以函數方式是因為減少他重新沒必要抓取狀態)

  const [isLandscape, setIsLandscape] = useState(() =>
    window.matchMedia("(orientation: portrait)").matches ? "portrait" : "landscape",
  )

翻轉事件名稱:orientationchange

所以就用 useEffect 去做監聽

這邊要注意的是,翻轉事件會在 matchMedia 的 “(orientation: portrait)” 之前發生

所以做了一個 timeout,他才會是正確的狀態

  useEffect(() => {
    const handleFlip = () => {
      // 延遲才會得到翻轉後的值
      setTimeout(() => {
        setIsLandscape(window.matchMedia("(orientation: portrait)").matches ? "portrait" : "landscape")
      }, 100)
    }

    window.addEventListener("orientationchange", handleFlip)
    return () => {
      window.removeEventListener("orientationchange", handleFlip)
    }
  }, [])