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

masonry-rails で Pinterest風Webアプリを作る

rails javascript jquery

※ mansory-rails で使用されている mansory の version が低いため現在は未使用。Responsive で利用する場合は、個別にmansoryを導入する必要があります。

Pinterest風のサイズの異なるグリッドをおしゃれに複数並べて
ブラウザリサイズ時に再配置してくれる Masonry を使ってみました。

Railsで取り込む際には、 以下が便利です。
kristianmandrup/masonry-rails: JQuery Masonry ready for use with Rails asset pipeline

how to install

gem入れて、CSS、JS、HTMLのclass属性を追加すれば良いです。

application.css

必要でないものは入れなくて良いです。centered、infinitescroll、right-to-left などは入れていません。

*= require 'masonry/basic'
*= require 'masonry/centered'
*= require 'masonry/fluid'
*= require 'masonry/gutters'
*= require 'masonry/infinitescroll'
*= require 'masonry/right-to-left'
*= require 'masonry/transitions'

application.js

jQuery使う場合は以下。他にも3.2.2以降はjQueryなしでも動くようになっているようです。

//= require masonry/jquery.masonry

一覧用html,css,js

一覧用html
id=masonry-container で囲って、transitions-enable など必要なやつを追加します。

<div id="masonry-container" class="transitions-enable clearfix">
  <div class="box">...</div>
  <div class="box">...</div>
  <div class="box">...</div>
  ...

css
この辺りは適当に。

#masonry-container {
  background: #FFF;
  padding: 5px;
  margin-bottom: 20px;
  border-radius: 5px;
  clear: both;
  -webkit-border-radius: 5px;
     -moz-border-radius: 5px;
          border-radius: 5px;
}

.clearfix:before, .clearfix:after { content: ""; display: table; }
.clearfix:after { clear: both; }
.clearfix { zoom: 1; }

js

$(function(){

  $('#masonry-container').masonry({
    itemSelector: '.box',
    columnWidth: 100,
    gutterWidth: 40
  });

});

はまりどころ

paginateにkaminariを利用したのですが、
どうも次のページ遷移時に上記jsの masonry() が実行されないようでした。

stackoverflowを見ると解決方法がありました。
javascript - Rails 4: how to use $(document).ready() with turbo-links - Stack Overflow

Turbolinksと相性悪いようです。
readyが呼ばれないというtubolinksあるあるですね。
パフォーマンス求めないwebアプリなので正直Turbolinks切ってもいいのですが、 一旦、以下のように書き直して事なきを得ました。(Rails5: coffeescript
※2016/10/10 修正版参照。

$(document).on 'turbolinks:load', ->
  $('#masonry-container').masonry
    itemSelector: '.box',
    columnWidth: 100,
    isAnimated: true,
    gutterWidth: 40,~~

2016/10/9 追記
やっぱりtubolinksのせいでレイアウトが綺麗に揃わない場合があったので、
以下のようにしてoffりました。

<div class="row" data-turbolinks="false">

2016/10/10 追記
どうも画像の読み込みタイミングによってレイアウトがずれることがあったので
onload で処理するように修正。

$(window).load ->
  $('#masonry-container').masonry
    itemSelector: '.box',
    columnWidth: 100,
    isAnimated: true,
    gutterWidth: 20,