変わりすぎて面食らう
ひょんな拍子にTurbolinks 5を使うことになったのですが、新機能を使わない状況であっても、ことごとくと言っていいぐらいに記法が変化していました。
なお、「Turbolinks Classic」は、Turbolinks 5が出た後に、Turbolinks 2.xに付けられた名称です。
<head>内の記述
Turbolinks Classicでは、JavaScriptやCSSの変化を検知するために、data-turbolinks-trackという属性を指定することになっていましたが、Turbolinks 5では、このdata-turbolinks-track属性にreloadという値を指定する必要があります。
<!-- classic -->
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
<!-- 5 -->
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => 'reload' %>
キャッシュ
Classicでも、過去に見たページはキャッシュした上で、戻った時にそれを表示するというような処理を行っていましたが、Turbolinks 5では、そのキャッシュを、同じアドレスに再度アクセスした際にもプレビューとして表示する、という仕組みが取り入れられています。これを止めてClassic相当の処理に戻したい場合は、メタタグで制御することとなります。なお、content=no-cacheとした場合、戻った時にもキャッシュが効かず再読み込み、という挙動になります。
<meta name="turbolinks-cache-control" content="no-preview">
一部止める
Classicでは、data-no-turbolink属性のついたリンク、あるいはこの属性が付く要素の中にあるリンクについてはTurbolinksが無効となっていましたが、Turbolinks 5ではdata-turbolinks="false"という指定が必要となります。なお、Turbolinksを無効にした親要素の中で、一部のリンクだけ有効にすることもできるようになっています。
<div data-turbolinks="false">
<a href='...'>このリンクは親要素で無効になっているのでTurbolinksが無効</a>
<a href='...' data-turbolinks="true">こっちは有効</a>
</div>
イベント名
Turbolinksの動作ごとにdocumentでJavaScriptのイベントが発生しますが、これまた別な名前となっています。
| Turbolinks 5 | Classic | イベントの発動タイミング |
|---|---|---|
turbolinks:click |
(なし) | Turbolinksの効いたリンクをクリックした時 |
turbolinks:before-visit |
page:before-change |
Turbolinksによる遷移が始まる直前(キャンセル可能) |
turbolinks:visit |
(なし) | Turbolinksによる遷移が始まった時 |
turbolinks:request-start |
page:fetch |
XHRのリクエストが飛ぶ直前 |
turbolinks:request-end |
page:receive |
XHRのリクエストが終了したタイミング |
turbolinks:before-cache |
(なし?) | 現在のページをキャッシュに保存する直前 |
turbolinks:before-render |
page:before-unload |
DOM描画の直前 |
turbolinks:render |
page:change/page:restore
|
DOM変更の完了 |
turbolinks:load |
page:load |
ページの表示時 |
loadイベントのタイミングとjquery.turbolinks
名前は違えどどちらでもloadイベントは起きますが、少し違いがあります。
- Turbolinks Classic…最初の読み込み時には
page:loadは起きない。 - Turbolinks 5…最初の読み込み時にも
turbolinks:loadが起きる。
ということで、Classic時代に$(document).on('ready page:load')と書いていたようなコードは、Turbolinks 5では$(document).on('turbolinks:load')だけでよくなります1。一方で、jquery.turbolinksを使って、ページ遷移のたびにreadyが発動するようにしていた場合、jquery.turbolinksのイベント名だけを書き換えて適用しようとすると、イベントが2回発動してしまいます。以下のように書いて、readyをturbolinks.loadに変換してしまいましょう。
(function($){
'use strict';
$.fn.ready = function(func){
$(document).on('turbolinks:load', function () {
func($);
});
};
})(jQuery);
-
もっとも、
readyを.onで登録すること自体が非推奨となっているとのことです。 ↩