Running masonry script depending on viewport width

My newest theme will use the Masonry script to display image grids. But I only need this function if the viewport is wider than a particular width. If the viewport is narrower than this width, the images are displayed below each other, and for that, I do not need to initialize the script. This post shows you how to get this behavior working.

At first the preliminary. It is not enough to check the viewport width on page load and run the script or not, depending on the result of the viewport width test. We also want to consider the case of resizing the viewport, and then possibly run the script or destroy a running instance. Besides that, we want to make it possible to use multiple grids per page.

That is the finished script (my first attempt had a small but critical error — the final version owes its smooth operation to the help of David DeSandro):

;(function () {
    var msnry;
    /**
     * Get the gallery grids.
     *
     * @type {NodeList}
     */
    var gridElems = document.querySelectorAll(".gallery-grid");

    /**
     * Check if we have grid elements.
     */
    if (0 === gridElems.length) {
        return
    }

    /**
     * Function for creating and destroying the masonry grids.
     */
    function masonryGrid() {
        var w = Math.max(
            document.documentElement.clientWidth,
            window.innerWidth || 0
        );

        /**
         * Only init masonry if the window is greater or equal 730px
         */
        if (w >= 730 && !msnry) {
            for (var i = 0; i < gridElems.length; i++) {
                msnry = new Masonry(gridElems[i], {
                    itemSelector: ".gallery-grid-item",
                    columnWidth: 1,
                    gutter: 0,
                    transitionDuration: 0,
                    resize: true,
                    fitWidth: true
                });
            }
        } else if (w < 730 && msnry) {
            for (var i = 0; i < gridElems.length; i++) {
                msnry = Masonry.data(gridElems[i]);
                msnry.destroy();
            }
            msnry = null;
        }
    }

    document.addEventListener("DOMContentLoaded", masonryGrid);
    window.addEventListener("resize", masonryGrid);
})();

At first, we create the msnry variable and get a NodeList of all elements which should become Masonry grids later. After checking if we have items in the NodeList, it follows the masonryGrid() function which is responsible for initializing the masonry script.

In the function, we look for the current viewport width and save it. After that, we check if the result is larger than or equal 730 and if the Masonry variable does not contain something. If this test fails, that means that the Masonry instance(s) are already running and we do not need to initialize them.

Afterward, we loop through the grid elements and create a Masonry grid for each (the instance of the last run remains in msnry). If the width is smaller than 730 and msnry contains something, we loop again and destroy the Masonry instances. After that, we set the msnry value to null.

Finally, we insert two event listeners, so that the function is called on page load and resizing of the viewport.

Related posts

Leave a Comment

Your email address will not be published. Required fields are marked *