カテゴリー:
JavaScript
タグ:
 Rails jQuery ページ遷移 アニメーション

このエントリーをはてなブックマークに追加
更新日時:
2013年03月03日(日)
作成日時:
2013年02月27日(水)

前の記事 / 次の記事

目次

  1. やりたいこと
  2. やってないこと
  3. 前提作業と実行環境
  4. コーディング
  5. 実用性
  6. 参考ページ

1.やりたいこと

githubみたいなページ遷移したい。
ページの一部だけスライドしてページ遷移するやつ。

次のページのREADME.MDを読もうとすると発生するエフェクトを実現したい。
jquery-pjax

2.やってないこと

githubではブラウザの戻るボタン、進むボタンを押した時も要素がスライドして
切り替わるようになっているけどそれは必要と思わなかったので実現してない。

このページ見て仕込めば出来そうな気はする。
githubのURLをうまく扱うオシャレなアレ = pjax

3.前提作業と実行環境

今回使ったRuby、Rails及び各スクリプトのバージョンは次の通り。

Ruby: 1.9.3p286
Rails: 3.2.11
jQuery: 1.9.1
jQueryUI: 1.9.2
pjax: 1.4.0

次の3つの機能がインストールされている必要があるので事前にインストール

  • jQuery
  • jQueryUI
  • pjax

3-1.jQueryとjQueryUIのインストール

$ vi Gemfile
gem 'jquery-rails'
gem 'jquery-ui-rails'

$ bundle install

3-2.pjaxのインストール

Rails上でのpjaxについて調べたのでメモを参照

3-3.各スクリプトの読み込みを宣言

$ vi app/assets/javascripts/application.js
//
//= require jquery
//= require jquery_ujs
//= require jquery.ui.all
//= require jquery.pjax

4.コーディング

4-1.コントローラー

コントローラーでの pjax の処理はRails上でのpjaxについて調べたのでメモを参照

4-2.ビュー

まずビューの用意。

ブログの記事を表示するビューで、前の記事をクリックすると前の記事へ、
次の記事をクリックすると次の記事へ遷移するようなビューを考える。

レイアウト

$ vi apps/views/layouts/application.html.haml
%html
  %title=@title
    =stylesheet_link_tag    "application", :media => "all"
    =javascript_include_tag "application"
%body
  %div#content
    =yield

個別のテンプレート

$ vi apps/views/articles/show.html.haml
-# @article.prev で前の記事を
-# @article.next で次の記事を呼び出せるように実装されているものとする。
%p
  =link_to("前の記事", @article.prev, class: "pjax prev")
  |
  =link_to("次の記事", @article.next, class: "pjax next")

%h1=@article.title
%p
  =@article.description

4-3.JavaScript

pjaxのコールバックにエフェクトを仕込んでもある程度エフェクトしてくれるのだけど、
エフェクト途中でページ遷移してしまったり、そもそもエフェクトされなかったりして
タイミングが微妙なので、

リンクがクリックされた時に即pjaxを発火させるのではなく、
リンクがクリックされた時は関数を呼び出し、その関数の中でpjaxを発火させている。

やっていることは次の通り。

  1. まず、今表示している遷移前の内容を非表示の要素として確保する
  2. 次に、ページを遷移させる
  3. 確保した遷移前の内容を表示させる
  4. 遷移後の内容を非表示する
  5. 遷移前の内容をスライドさせながら非表示にする
  6. 遷移後の内容をスライドさせならが表示させる

っていうので出来ると思ったし、まあビジュアル的にはちゃんと動いたんだけど、
「2.次に次に、ページを遷移させる」っていうのは実際はコールバックで仕込まないと
順番は保証されなくて、「6.遷移後の内容をスライドさせならが表示させる」の後に
書いても「1.まず、今表示している遷移前の内容を非表示の要素として確保する」の
前に書いても結果は同じっていう。

スライドさせる部分でしかpjax使わないなら
$(document).on("pjax:complete", func()) とかに仕込めばいいけど、
たぶんそうじゃないから、まあとりあえず分からん(笑)

”次の記事” がクリックされた時の処理

$ vi app/assets/javascripts/github_effect.js
$ ->
  $(document).on("click", "a.pjax.next", (event)->
    pjax_container = "#content"

    # 遷移前の内容を $shadow として確保
    $shadow  = $(pjax_container).clone().attr("id", "shadow").hide()
    # 本来の内容が表示される場所に被るように重ねて配置する
    $shadow.insertBefore(pjax_container)
    $shadow.css("position", "absolute").css("top", 0)

    # ここで発火させてページ遷移
    $.pjax.click(event, container: pjax_container)

    # 遷移後の要素を一旦非表示にしてスライドさせながら表示させる
    $(pjax_container).hide().show("slide", direction: "right", 450)
    # 遷移前の要素を一旦表示させてスライドさせながら非表示にする
    $shadow.show().hide("slide", direction: "left", 450)
  )

”前の記事” がクリックされた時の処理

$ vi app/assets/javascripts/github_effect.js
$ ->
  $(document).on("click", "a.pjax.next", (event)->
    pjax_container = "#content"

    $shadow  = $(pjax_container).clone().attr("id", "shadow").hide()
    $shadow.insertBefore(pjax_container)
    $shadow.css("position", "absolute").css("top", 0)

    $.pjax.click(event, container: pjax_container)

    -# 次の left と right が違うだけ
    $(pjax_container).hide().show("slide", direction: "left", 450)
    $shadow.show().hide("slide", direction: "right", 450)
  )

5.実用性

ある程度のスペックがあるマシンならサクサク動くのかも知れないけど、
自分の環境だと大きな領域を動かそうとすると結構カクついたので、
今のところはまだ、githubがそうしてるように、使うなら小さな領域にだけ
使った方がいいのかも知れない。

6.参考ページ

jquery-pjax
githubのURLをうまく扱うオシャレなアレ = pjax
jQuery UI 日本語リファレンス

サンプルは、ない。