Search code examples
javascriptmedia-querieswidth

Run JS MediaQuery on initial load AND on change


I want to load a specific JavaScript snippet only for screen sizes with a minimum width of 1001px to speed up loading time for smaller devices. Therefore I used the MediaQuery feature to identify the min-width and react on a change like this:

            const mediaQuery = window.matchMedia('(min-width: 1001px)');
            mediaQuery.addEventListener('change', (event) => {
                if (event.matches) var t = (0, s.qs)(".js-twitter-feed");
                if ("undefined" != typeof twitterFeed && t) {
                    t.classList.remove("u-hide");
                    var r = document.createElement("div");
                    r.innerHTML = '<a class="twitter-timeline" data-height="500" href="https://twitter.com/'.concat(twitterFeed, '">Tweets by ').concat(twitterFeed, "</a>"), t.appendChild(r), (0, o.loadScript)("https://platform.twitter.com/widgets.js")
                }
            });

The problem with this snippet is, that it is only loading the included Twitter widget when a screen size change was performed once and not already when the page is loading and min-width 1001px is true already. That is why I searched for another solution which looks like this:

if (matchMedia) {
    const mq = window.matchMedia("(min-width: 1001px)");
    mq.addListener(WidthChange);
    WidthChange(mq);
}

// media query change
function WidthChange(mq) {

    var t = (0, s.qs)(".js-twitter-feed");
                        if ("undefined" != typeof twitterFeed && t) {
                            t.classList.remove("u-hide");
                            var r = document.createElement("div");
                            r.innerHTML = '<a class="twitter-timeline" data-height="500" href="https://twitter.com/'.concat(twitterFeed, '">Tweets by ').concat(twitterFeed, "</a>"), t.appendChild(r), (0, o.loadScript)("https://platform.twitter.com/widgets.js")
                        }
}

This code loads the Twitter widget also for screen sizes with a width of less than 1001px. How can I solve this?


Solution

  • What you need is a function to test the media query, which you shall call once on document load and also add as a handler for the mediaQuery change event. Here is a working sample code:

    <html>
    <head>
    <script>
    
    function run()
    {
        const contentDiv = document.getElementById("content");
        const mediaQuery = window.matchMedia("(min-width: 1001px)");
        function onMediaQueryChange()
        {
            if(mediaQuery.matches) contentDiv.innerHTML = "LARGE";
            else contentDiv.innerHTML = "small";
        }
    
        // will react on later changes
        mediaQuery.onchange = onMediaQueryChange;
    
        // will handle the initial browser window size
        onMediaQueryChange();
    }
    
    </script>
    </head>
    <body onload="javascript:run()">
    <div id="content"></div>
    </body>
    </html>

    Your code could look like something like this (not tested):

    const mediaQuery = window.matchMedia('(min-width: 1001px)');
    function mediaQueryChange(mediaQuery)
    {
        if (mediaQuery.matches) var t = (0, s.qs)(".js-twitter-feed");
        if ("undefined" != typeof twitterFeed && t) {
            t.classList.remove("u-hide");
            var r = document.createElement("div");
            r.innerHTML = '<a class="twitter-timeline" data-height="500" href="https://twitter.com/'.concat(twitterFeed, '">Tweets by ').concat(twitterFeed, "</a>"), t.appendChild(r), (0, o.loadScript)("https://platform.twitter.com/widgets.js")
        }
    };
    mediaQuery.addEventListener('change', mediaQueryChange);
    mediaQueryChange(mediaQuery);