Sprints: MediaQueryList does not inherit from EventTarget on Safari and Safaria on iOS

Created on 26 Jan 2019  路  7Comments  路  Source: mdn/sprints

Request type

  • [ ] New documentation
  • [x] Correction or update

Page to change

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

Details

The MDN web docs state that the MediaQueryList objects is inheriting from EventTarget in nearly all modern browsers. Thus you could (and probably should) use addEventListener('change', callback) instead of the alias addListener(callback). But it seems to me that on Safari this isn't the case.

You can verify this by running the following commands:

 // Will work in all browsers
window.matchMedia("foo").addListener(() => null);

// Might throw TypeError on iOS/macOS, complaing that window.matchMedia(...).addEventListener is not a function
window.matchMedia("foo").addEventListener("change", () => null);

Related issues

https://github.com/mdn/browser-compat-data/pull/1235

WebAPI Medium P1

Most helpful comment

I also had a hard time finding this out, and I was just about to submit this bug, when I saw that a discussion already exists. So I'll just paste my message in here, which might be useful, because I looked through the affected pages on MDN. Btw, I also just reported this to caniuse.com

Support for matchMedia is only partial in Safari (Desktop and iOS) including Safari 13 (Technology Preview), because the MediaQueryList object that is returned only supports the legacy .addListener() method, but not .addEventListener().
See: https://developer.apple.com/documentation/webkitjs/mediaquerylist
Test:
const mediaQuery = matchMedia("(min-width: 1000px)");
console.log("addEventListener" in mediaQuery);
This is problematic, because this page says that you can "watch for a change event", which implies using addEventListener:
https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia

Also it points to the example on this page, where addEventListener is used:
https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Example

The table on the page with the example has Safari green and fully supporting, but in fact you just have to open the console to see this: "TypeError: matchMedia(mqString).addEventListener is not a function. (In 'matchMedia(mqString).addEventListener("change", updatePixelRatio)', 'matchMedia(mqString).addEventListener' is undefined)"

On this page, only .addListener() is used, so it is correct, but it says that it would be only an alias for addEventListener "for backward compatibility purposes", without mentioning the lack of support in Safari and the different syntax of the two methods: .addListener needs a function as first argument, not a string like .addEventListener. So "alias" is probably not the correct term:
https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList

Everything above also is true for .removeEventListener (not supported in Safari) vs. .removeListener.

All 7 comments

Any updates on this? I'm running into this very issue in iOS 12.2. It was extremely confusing because just about every reference for addEventListener out there implies that it works fine on iOS (Mobile Safari).

I also had a hard time finding this out, and I was just about to submit this bug, when I saw that a discussion already exists. So I'll just paste my message in here, which might be useful, because I looked through the affected pages on MDN. Btw, I also just reported this to caniuse.com

Support for matchMedia is only partial in Safari (Desktop and iOS) including Safari 13 (Technology Preview), because the MediaQueryList object that is returned only supports the legacy .addListener() method, but not .addEventListener().
See: https://developer.apple.com/documentation/webkitjs/mediaquerylist
Test:
const mediaQuery = matchMedia("(min-width: 1000px)");
console.log("addEventListener" in mediaQuery);
This is problematic, because this page says that you can "watch for a change event", which implies using addEventListener:
https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia

Also it points to the example on this page, where addEventListener is used:
https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Example

The table on the page with the example has Safari green and fully supporting, but in fact you just have to open the console to see this: "TypeError: matchMedia(mqString).addEventListener is not a function. (In 'matchMedia(mqString).addEventListener("change", updatePixelRatio)', 'matchMedia(mqString).addEventListener' is undefined)"

On this page, only .addListener() is used, so it is correct, but it says that it would be only an alias for addEventListener "for backward compatibility purposes", without mentioning the lack of support in Safari and the different syntax of the two methods: .addListener needs a function as first argument, not a string like .addEventListener. So "alias" is probably not the correct term:
https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList

Everything above also is true for .removeEventListener (not supported in Safari) vs. .removeListener.

I've just spent the best part of half a day realising what @makkabi explained. It's very confusing as the errors in Safari don't allude to the how the the problem occurs.
I resolved the issues I was facing by using addListener instead of addEventListener.

This one has been hanging around way too long; @a2sheppy can you take this as a P1 bug in the next sprint?

Will do.

Parts of the changes around this have already been made; the BCD tables have been updated since this issue was filed. However, I'm going to add some text explaining that addListener() and removeListener() are for backward compatibility and that it's generally preferable to use the EventTarget counterparts now.

I've made assorted text improvements, as well as submitted [BCD PR 6403](mdn/browser-compat-data#6403) to add notes to the interface on Safari and Safari iOS to be sure this issue is clear; these notes also mention this should be resolved in iOS 14 and macOS 11 Big Sur. Made some other fixes as well. See the PR for further details.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

marcvangend picture marcvangend  路  5Comments

krankj picture krankj  路  3Comments

ExE-Boss picture ExE-Boss  路  6Comments

mattiapontonio picture mattiapontonio  路  5Comments

Elchi3 picture Elchi3  路  8Comments