utamaro’s blog

誰かの役に立つ情報を発信するブログ

可変グリッドレイアウトをMuuriで実装する

画面サイズを変えると、中のグリッドがグリグリと動く画面を作ってみます。

github.com

npmでインストールします。

npm install muuri

注意事項

ドラッグして要素を動かす場合は以下のライブラリをインストールする必要があります。

npm install hammerjs

npmを使わずに実装する場合は↓を全て入れると良いです。

(ドラッグを使わない場合はhammerjsを抜いて良いです。

<script src="https://unpkg.com/web-animations-js@2.3.1/web-animations.min.js"></script>
<script src="https://unpkg.com/hammerjs@2.0.8/hammer.min.js"></script>
<script src="https://unpkg.com/muuri@0.7.1/dist/muuri.min.js"></script>

実装例

この実装例では、scssやnpmを使っているため別途ビルドが必要です。

cssや、import箇所を修正することでビルドが必要なくなります。

index.html

<div class="main">
    <div class="grid">
        <div class="item">
            <div class="item-content">
                <div class="ss">hoge1</div>
            </div>
        </div>
        <div class="item">
            <div class="item-content">
                <div class="ss">hoge2</div>
            </div>
        </div>
        <div class="item">
            <div class="item-content">
                <div class="ss">hoge3</div>
            </div>
        </div>
        <div class="item">
            <div class="item-content">
                <div class="ss">hoge4</div>
            </div>
        </div>
    </div>
</div>

script.js

jqueryを使っていた場合$(document).readyではうまく動作しないことがありました。

ページ更新時に画像要素が重なって表示されました。

おそらくreadyがDom構築が完了した段階で処理が実行されるためだと思います。

画像のサイズまで考慮されずに重なってしまったのかと。

loadにすると、画像の読み込みなどが完了してから実行されるので改善されました。

import $ from 'jquery';
import Muuri from 'muuri';

(function() {

    function init() {
        var grid = new Muuri('.grid');
    }

    $(window).on('load', function() {
        console.log("called ready function");
        init();
    })
})();

style.scss

.main {
    padding-top: 56px;
    height: 100%;
    box-sizing: border-box;
}

.grid {
    position: relative;

    .item {
        position: absolute;
        z-index: 1;
        background: #fff;
        width: 100px;
        height: 100px;
        margin: 3px;
        border: 1px solid #d8d8d8;
        box-sizing: border-box;
    }
    .item.muuri-item-dragging {
        z-index: 3;
    }
    .item.muuri-item-releasing {
        z-index: 2;
    }
    .item.muuri-item-hidden {
        z-index: 0;
    }
    .item-content {
        position: relative;
        width: 100%;
    }
}

エラー対応

Uncaught TypeError: url.indexOf is not a function

jqueryでloadを使おうとした際に置きました。

$(window).load(function() { ... });

ではなく、↓が正しいです。

$(window).on('load', function() { ... });