Search code examples
javascriptmedia-queries

How can I force a matching window.matchMedia to execute on page load?


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

  • the css version page is blue
  • the javascript version is white and changes its state only after a new condition is met, i.e. the window is sized below 601 px.

How can I force a matching window.matchMedia to execute on page load?


Solution

  • 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