読者です 読者をやめる 読者になる 読者になる

初めてのシステムと日記

システムも日記も初めてです。

Pinterest風のレイアウトが出来るWookmark jQuery pluginを使ってみた

jQuery

Pinterestのように要素をレンガ上に並べるレイアウトが近年流行っていますが、
そのレイアウトをシンプルなスクリプトで表示出来るのが「Wookmark」です。


The Wookmark jQuery plugin
github Wookmark-jQuery


■デモ


githubにあったサンプルをこちらに置きました。


■使い方

  • 外部ファイル

jquery.jsとwookmark.jsを読み込みます。

<script type="text/javascript" src="jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="jquery.wookmark.js"></script>
  • HTML

レンガ状にレイアウトするコンテンツをリスト要素で並列に並べます。
各要素のidは後述するwookmarkの実行で使用します。

// div:レイアウト全体の領域
// ul:レンガ状にするコンテンツのリスト要素
// li:各コンテンツ要素

<div id="main" role="main">
  <ul id="tiles">
    // 要素分を繰り返し
    <li><img src="images/image_1.jpg" width="200" height="283"><p>1</p></li>
  </ul>
</div>

リスト要素のidを指定してwookmarkを実行します。
必要に応じてオプションを指定します。

<script type="text/javascript">
  $(document).ready(new function() {
    var options = {
      autoResize: true, // ブラウザの拡大縮小に合わせて要素を自動でリサイズするかどうか
      container: $('#main'), // CSSを適用している要素を指定
      offset: 2, // 要素間の隙間を指定
      itemWidth: 210 // 各要素の幅を指定     
    };

    var handler = $('#tiles li'); // レンガ状にする要素を指定
      
    handler.wookmark(options); // wookmarkをオプション付きで実行
});
</script>


APIとか使って表示したい


HTMLに記述したコンテンツだけではなく、
もっと見るなどのユーザーのアクションをトリガーにしてjsでコンテンツを追加する場合

<script type="text/javascript">
  $(document).ready(new function() {
    /*
    wookmarkの実行がここに記述されてると想定
    */

    // ボタンをクリックしたらコンテンツを追加
    $("p").live("click", function(){
      $.ajax({
        url: 'example.json',
        dataType: 'json,
        success: function(data){
          var html='';
          var i=0, length=data.length;
          for(; i<length; i++) {
            html += '<li>';
            html += '<img src="'+data.img+'" width="200" height="'+data.height+'">';
            html += '<p>'+data.title+'</p>';
            html += '</li>';
          }
          $('#tiles ul).append(html);

          // wookmarkを一旦クリアして再度実行
          handler.wookmarkClear();
          handler = $('#tiles li');
          handler.wookmark();
       }
     });
  });
</script>

はじめはappendした後にhandler.wookmark()を実行したのですが、
appendはされるものの追加したコンテンツがタイル状にならず。。
APIを使ったサンプルを見る限り、JSなどで追加した場合は一旦handler.wookmarkClear()でコンテンツをクリアして
再度wookmarkを実行する必要があるようです。
(色々紹介しているブログは見たのですがこの辺があまり紹介されておらず結構苦労した。。)


■タイル要素の高さが動的な場合

タイル要素内の画像の高さが指定されていない(画像を動的に表示してるとかの理由で)場合
画像の読込が遅いと読み込まれる前にwookmarkが実行され、
タイル要素の高さが画像なしの高さになってレイアウトが崩れてしまう場合があります。


その場合、setTimeout関数でわざと遅延させてwookmarkを実行させたり、

<script type="text/javascript">
  $(document).ready(new function() {
    // 3秒後にwookmarkを実行
    setTimeout(function(){
      /*
      wookmarkの実行がここに記述されてると想定
      */
    }, 3000);
  });
</script>


load関数で最後のタイル要素内の画像が読み込まれたら実行とかで多少回避出来るかと思います。
※load関数はIEでは対応していないようです。

<script type="text/javascript">
  $(document).ready(new function() {
    // 最後のタイル要素内の画像が読み込まれたら実行
    $("#tiles li:last img").load(function(){
      /*
      wookmarkの実行がここに記述されてると想定
      */
    });
  });
</script>