使用JS媒體查詢,MediaQueryList全解析

本文來自個人博客javascript

什麼是MediaQueryList

一個MediaQueryList對象在一個document上維持着一系列的媒體查詢,並負責處理當媒體查詢在其document上發生變化時向監聽器進行通知的發送。java

若是你須要以編程方式來檢測一個document上的媒體查詢的值的變化,這個MediaQueryList對象使得經過觀察其document而檢測它的媒體查詢的值的變化成爲可能,而不是週期性地對這些媒體查詢的值進行檢查。編程

簡單來講,MediaQueryList就是提供給JavaScript進行媒體查詢的方法瀏覽器

兼容性方面也挺好函數

先來看看MediaQueryList的屬性和方法ui

屬性spa

  • matches 返回媒體查詢的結果
  • media 返回媒體查詢的內容
  • onchange 媒體查詢狀態變化時觸發的事件

方法3d

  • addListener() 當媒體查詢狀態變化時觸發的自定義回調
  • removeListener() 移除自定義回調

matches

matchesMediaQueryList的只讀屬性,返回一個布爾值,當媒體查詢匹配時返回ture,反之falsecode

先要建立一個MediaQueryList對象orm

const mql = window.matchMedia("(max-width:1600px)");
複製代碼

經過matches屬性獲取媒體查詢的結果

if (mql.matches) console.log("屏幕寬度小於1600px"); // 若是恰好1600也返回true
else console.log("屏幕寬度大於1600px");
複製代碼

經過這個方式能夠很容易的判斷當前系統的主題

let pref = window.matchMedia("(prefers-color-scheme: light)");
if (pref.matches) console.log("light");
pref = window.matchMedia("(prefers-color-scheme: dark)");
if (pref.matches) console.log("dark");
複製代碼

在實現頁面主題的切換功能時能夠用到

media

media屬性會返回填寫的媒體查詢匹配規則

const mql = window.matchMedia("(max-width:1600px)");
console.log(mql.media); // (max-width: 1600px)
複製代碼

addListener/removeListener

addListener添加自定義回調,在媒體查詢的狀態改變時會調用回調

const mql = window.matchMedia("(max-width:1600px)");
const cb = e => {
  if (e.matches) console.log("屏幕寬度小於1600px");
  else console.log("屏幕寬度大於1600px");
};
mql.addListener(cb);
// 移除回調函數
mql.removeListener(cb);
複製代碼

在頁面加載完成後,不會觸發此回調,必定得手動拖動窗口大小後纔會觸發

有小夥伴就要問了,onchange屬性呢,且容我細細道來

onchange

先來看代碼

const mql = window.matchMedia("(max-width:1600px)");
const cb = e => {
  if (e.matches) console.log("屏幕寬度小於1600px");
  else console.log("屏幕寬度大於1600px");
};
mql.onchange = cb;
複製代碼

在Chrome上一切正常,然而在Safari上毫無反應

在看看Can i use

爲何兼容性忽然就變成這樣了?

在使用addListener的時候,我發現了在Webstorm裏addListener竟然劃了橫線標註了廢棄的方法

不只addListenerremoveListener也廢棄了,同時發現了兩個新方法addEventListenerremoveEventListener

addEventListener/removeEventListener

addEventListener的使用方式和DOM2級事件綁定方式相同

const mql = window.matchMedia("(max-width:1600px)");
const cb = e => {
  if (e.matches) console.log("屏幕寬度小於1600px");
  else console.log("屏幕寬度大於1600px");
};
mql.addEventListener("change", cb);
// mql.removeEventListener("change", cb);
複製代碼

在Chrome上一切正常,在Safafi上就報錯了mql.addEventListener is not a function,這也許能解釋爲何onchange兼容性很差了

同時我發現,使用addListener方法添加的事件,參數e在Chrome上和Safari上也是兩個不一樣的東西

在Chrome上,它是一個Event對象,在Safari上只是包含了matchesmedia屬性的對象,在看看兼容性

看上去Chrome也是才支持的

在MDN上是這樣寫的

MediaQueryList.addListener()方法只是爲了向後兼容EventTarget.addEventListener()的一個別名,在老的瀏覽器上應該使用addListener而不是addEventListener,由於MediaQueryList只重新的瀏覽器繼承EventTarget

我想這只是爲了規範化吧,看來新的瀏覽器Chrome 80也不夠新啊,仍是老老實實看着標灰劃個線用addListener就好了


參考資料:

MDN:developer.mozilla.org/zh-CN/docs/…

相關文章
相關標籤/搜索