I noticed a difference between css media query definition and the javascript window.matchMedia media query definition:
The css rules are apllied initially to a loaded page.
The rules defined in javascript are not executed after the page load, but only after a new condition is entered.
An example:
I have two different pages with equivalent media query definitions, the first one defined in css and the second one defined in javascript:
the css version (defined in a style element):
@media (min-width: 401px) and (max-width: 600px) { body {background-color: red; } }
@media (min-width: 601px) and (max-width: 800px) { body {background-color: blue; } }
the javascript version (defined either globally or in a function called after body onload):
window.matchMedia("(min-width: 401px) and (max-width: 600px)")
.addListener(function(e) {
if (e.matches) {
document.body.style.background = "red";
}
});
window.matchMedia("(min-width: 601px) and (max-width: 800px)")
.addListener(function(e) {
if (e.matches) {
document.body.style.background = "blue";
}
});
When I load a page and the window is 700 px wide
How can I force a matching window.matchMedia to execute on page load?
To fire a matchMedia
on load, you could do like this instead (with a somewhat cleaner code base).
Stack snippet
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
document.addEventListener("DOMContentLoaded", function(e) {
// medias (as an array to make it a little easier to manage)
var mqls = [
window.matchMedia("(max-width: 400px)"),
window.matchMedia("(min-width: 401px) and (max-width: 600px)"),
window.matchMedia("(min-width: 601px) and (max-width: 800px)"),
window.matchMedia("(min-width: 801px)")
]
// event listeners
for (var i=0; i<mqls.length; i++){
mqls[i].addListener(mqh)
}
// matches methods
function mqh(){
if (mqls[0].matches) {
console.log("CALLBACK (max-width: 400px)");
document.body.style.background = "green";
} else if (mqls[1].matches) {
console.log("CALLBACK (max-width: 600px)");
document.body.style.background = "red";
} else if (mqls[2].matches) {
console.log("CALLBACK (max-width: 800px)");
document.body.style.background = "blue";
} else if (mqls[3].matches) {
console.log("CALLBACK (min-width: 801px)");
document.body.style.background = "gray";
}
console.log("window.innerWidth: " + window.innerWidth);
}
// call once on load
mqh();
});
</script>
</head>
<body>
</body>
</html>
Org. src: http://www.javascriptkit.com/javatutors/matchmediamultiple.shtml
A callback function bound to window.matchMedia is not called on page load.
A solution to the problem would be:
if(window.matchMedia("...").matches){
<body onload
window.onresize
I was facing the same problem today, and I've used the following solution inspired by Nathan:
const gate = 800
function listener(
matches,
) {
document.getElementById('tag').innerHTML = matches ? 'wider' : 'narrower'
}
window.onload=() => {
const match = window.matchMedia(`(min-width: ${gate}px)`)
match.addListener(e => listener(e.matches))
listener(match.matches)
}
<h1>
This window is
<span id='tag'></span>
than 800px
</h1>
The core concept is to run your listener function once with MediaQueryList.matches passed as a parameter.
And if someone is trying to achieve this with a framework, do remember to register and trigger the listener during the component mount event.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With