masonry + ajaxでpinterest風タイルビューを実現する

  • 34
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

top.png

pinterestのような、
・要素を隙間なく敷き詰める
・ブラウザのリサイズに応じて配置も変わる
といった機能を持つタイルビューを実現するjsのライブラリはいくつかあります

その中でも今回は定番のmasonryを使い、
ajaxでページングして下に下にコンテンツをページ遷移なしで追加してみます
基本的なmasonryの使い方は他に記事が大量にあるのでここでは解説しませんよ!

完成イメージは(手前味噌ですが)こんなかんじです↓
tokyotownname.com

では始めます、
画像がいくつかトップにあり、
その下に「もっと読む」ボタンがあるとします。ありがちですね。


<!-- タイルビュー -->
<div id="images">
  <div id="image-unit">....</div>
  <div id="image-unit">....</div>
  ......
  <div id="image-unit">....</div>
  <div id="image-unit">....</div>
</div>

<!-- もっと読むボタン -->
<a href="javascript:void(0)" id="read-more">もっと読む</a>


window.onload = function() {
  $("#images").masonry({
    itemSelector: '#image-unit',
  });
}

2ページ目の画像たちを表示させるhtmlをajax経由で取ってきましょう
取ってきたhtmlはコンテナである$("images")にappendします
現在のページ数はwindow.pagingに保存しておくとします


$('#read-more').click(function() {
  $.ajax({
    url: "photos/",
    type: "GET",
    data: { page: window.paging },
    dataType: "html",
    beforeSend: function(){ $('#read-more').text("読み込み中..."); },
    success: function(data){
      if (data != '') {
        $container = $("#images");
        $container.imagesLoaded(function(){
          var el = $(data);
          el.css('display', 'none');
          $container.append(el);
          $container.imagesLoaded(function(){
            el.css('display', 'inline');
            $container.masonry('appended', el, true);
            $('#read-more').text("もっと読む");
          });
        });
      } else {
        $('#read-more').text("もう画像はありません");
      }
    },
    error: function(data){
      console.log("some error occured! majioco! punpunmaru!");
    }
  });
})

コールバックのsuccessに次ページのhtmlが返ってきます。
これを jQueryオブジェクトにした後にコンテナのimagesにappendして、
masonryのappendedメソッドを呼んで整列させればいいのですが、
正しくmasonryが画像の位置を決めるためには
画像がすべて読み込まれてからじゃないといけない点に注意しましょう
でないと縦横のサイズが分からないのでmasonryさんが位置を計算できないのです

なので、imagesLoaded.jsを使って
コンテナに追加した次ページのhtml内の画像がすべて読み込まれるのを待ってから、
masonryのappendedで整列処理を行います

$container = $("#images");
$container.imagesLoaded(function(){
  var el = $(data);
  el.css('display', 'none');
  $container.append(el);
  $container.imagesLoaded(function(){
    el.css('display', 'inline');
    $container.masonry('appended', el, true);
    $('#read-more').text("もっと読む");
  });
});

また、コンテナに次ページのhtmlを追加して整列が完了するまでの間、
画像が未読み込みがhtmlがチラッと見えてしまい非常に見苦しい事になるので、
追加してすぐにdisplay:noneして隠してしまいましょう

以上です。コンテンツを楽しく見せる事ができるMasonryをぜひとも検討してみてください!