RailsのTurbolinks
Railsの勉強でWebアプリを作っていて、Turbolinksの存在をよく知らなかったために、ページ遷移したときにloadイベントが発生せずに困った話。
事象
今日は「トップに戻る」ボタンをjQueryを使って付けてみた。ある程度以上スクロールすると表示されるやつ。よく見かけるやつ。
これは検索すればいくらでもサンプルが出てくるし、問題なく付けることができた。しかし、いろいろと動作確認しているうちに、どうも挙動がおかしいことに気付いた。
ページをリロードしたときにはちゃんと動作するのに、アプリ内の別のページから遷移してきたときにはうまく動いていない。どうやら、loadイベントのハンドラが実行されていないように見える。
それで調べてみると、Rails 4から導入されてデフォルトで有効になっているTurbolinksという機能が、アプリ内のページ遷移を基本的にすべてAjax通信+DOMの更新に置き換えているとのこと。これによってアセットの再ダウンロードを省略できるなどのメリットがあるらしい。
どうやらこれのせいでページ遷移がなくなってloadイベントが呼ばれなくなってるようだ。
Turbolinksについてはちゃんとは知らなかったけど、名前は何度か目にしてたし、なんとなく今回の犯人ではないかと検討はついてた。
対策
対策としては、Turbolinksを無効にするか、TurbolinksがページのDOMを書き換えたタイミングでコードを実行するか。
受けられる恩恵はできるだけ受けたいので、後者にする。
Turbolinksはpage:change
イベントを提供していて、これがまさにページが切り替わったときに発生するイベントらしい。
これを使えばいいんだけど、手元の本では、
$(document).ready(init) $(document).on('page:change', init)
としていて、イディオムだと書いてある。
でも、上の行は必要なのかが気になった。page:change
だけで初回ロードも対応できないものだろうか?
TurbolinksのReadmeを見てみる。
page:change the page has been changed to the new version (and on DOMContentLoaded)
page:change the page has been changed to the new version (and on DOMContentLoaded)
初回でもいけるのかはわからない。
Turbolinksのソースを見てみる。以下が抜粋。
... installDocumentReadyPageEventTriggers = -> document.addEventListener 'DOMContentLoaded', ( -> triggerEvent EVENTS.CHANGE triggerEvent EVENTS.UPDATE ), true ... browserSupportsCustomEvents = document.addEventListener and document.createEvent ... if browserSupportsCustomEvents installDocumentReadyPageEventTriggers() installJqueryAjaxSuccessPageUpdateTrigger()
turbolinks/turbolinks.js.coffee at master · rails/turbolinks
(EVENTS.CHANGE
は'page:change'と定義されている)
これを見る限り、document.addEventListener
とdocument.createEvent
がサポートされていれば、DOMContentLoaded
のタイミングでpage:change
が発生するため、初回ロード時にも対応できそう。
document.addEventListener
とdocument.createEvent
はIE9以上であればサポートされているようなので、とりあえず今回はそれでOKとする。
ということで、
$ -> doSomething()
としていたところを
$(document).on 'page:change', -> doSomething()
に変えただけで済んだ。
まとめ
本当に今回の対応でよかったのかいまいち確信持てない。
あとRailsは裏で勝手にいろいろやってくれていて、それぞれ意味があってやってくれているんだろうけど、ちゃんと理解していないと思わぬ挙動に遭遇してビクッとする。
Ruby on Rails 4 アプリケーションプログラミング
- 作者: 山田祥寛
- 出版社/メーカー: 技術評論社
- 発売日: 2014/04/11
- メディア: 大型本
- この商品を含むブログ (3件) を見る