admin管理员组

文章数量:1135166

I'm making use of matchMedia().addListener to detect dark/light mode theme preference changes in Safari, however in WebStorm using addListener is marked as deprecated but simply says to refer to documentation for what should replace it.

I've had a read through the MDN docs and I don't understand what event type I should be listening for in addEventListener to replace addListener?

window.matchMedia("(prefers-color-scheme: dark)").addListener(() => this.checkNative());
window.matchMedia("(prefers-color-scheme: light)").addListener(() => this.checkNative());

I'm making use of matchMedia().addListener to detect dark/light mode theme preference changes in Safari, however in WebStorm using addListener is marked as deprecated but simply says to refer to documentation for what should replace it.

I've had a read through the MDN docs and I don't understand what event type I should be listening for in addEventListener to replace addListener?

window.matchMedia("(prefers-color-scheme: dark)").addListener(() => this.checkNative());
window.matchMedia("(prefers-color-scheme: light)").addListener(() => this.checkNative());
Share Improve this question edited Dec 21, 2020 at 23:58 Tyler2P 2,37030 gold badges25 silver badges32 bronze badges asked Jun 5, 2019 at 18:39 Matt CowleyMatt Cowley 2,3632 gold badges22 silver badges34 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 141

From the doc - https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/addListener

A function or function reference representing the callback function you want to run when the media query status changes.

It should be change event. https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/onchange.

const mql = window.matchMedia("(prefers-color-scheme: dark)");

mql.addEventListener("change", () => {
    this.checkNative();
});

Chrome and Firefox handle it differently than Safari, I solved it with way:

const darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

  try {
    // Chrome & Firefox
    darkMediaQuery.addEventListener('change', (e) => {
      this.$vuetify.theme.dark = !this.$vuetify.theme.dark;
    });
  } catch (e1) {
    try {
      // Safari
      darkMediaQuery.addListener((e) => {
        this.$vuetify.theme.dark = !this.$vuetify.theme.dark;
      });
    } catch (e2) {
      console.error(e2);
    }
  }

If you're interested in how to support Dark Mode with your website, read this blogpost.

If you just do as MDN writes it works cross browser (where it's supported):

const mql = window.matchMedia('(max-width: 767px)');
mql.onchange = (e) => { 
  /* ... */
}

Should be supported above IE. E.g. all Edge + modern browsers.

https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/onchange

Based On Szabó Csaba Answer

const darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

function onPrefersColorScheme(status: MediaQueryListEvent): void {
  // TODO
}

function tryChromeandFirefox() {
  darkMediaQuery.addEventListener('change', onPrefersColorScheme);
}

function trySafari() {
  darkMediaQuery.addListener(onPrefersColorScheme);
}

try {
  tryChromeandFirefox();
} catch {
  try {
    trySafari();
    // eslint-disable-next-line no-empty
  } catch {}
}

Also, single-line trying to invoke (not recommended):

// add `async` to
async function tryChromeandFirefox();
async function trySafari();

tryChromeandFirefox().catch(() => trySafari());

本文标签: