LoginSignup
3
1

More than 3 years have passed since last update.

Turbolinksでさらに発展系へ~data-turbolinks-permanent~

Posted at

Turbolinks 5で使えるオプション機能として、data-turbolinks-permanentというものがあります。

気になった動機

Rails+Turbolinks+Reactでシステムを組んでいて、Turbolinksでページごとのアセット読み込みは回避できるようになったのですが、Reactがページごとにマウント・アンマウントされるので、「同じものを再生成するコストが無駄」、また「Ajaxでロードするデータを何度も取ってくる必要がある」などの非効率な点があったので、そちらを改善したくなってきました。

そうしたところ、Turbolinksで対応できるとわかったので、取り入れてみた次第です。

data-turbolinks-permanentとは

Turbolinksで読み込むページ内に、<div id="some-id" data-turbolinks-permanent></div>のようにdata-turbolinks-permanent属性を指定したエレメントがあると、Turbolinksによるページ遷移の後も同じエレメントを再利用するようになります。なお、「idが同じ」ものだけ引き継がれますので、idの付与は必須となります。

JavaScriptの世界から見た挙動

もちろん、単なるHTMLを持ち越してもそこまで魅力があるわけではないので、主戦場はJavaScriptウィジェット、ということになります。ということで、イベント段階での挙動を見てみると、次のようになっていました。

  • turbolinks:before-render時点:永続する要素はまだdocument.bodyの中にあって、イベントで取ってこられるe.data.newBodyには上書きされる予定のdata-turbolinks-permanentつきエレメントが残っている
  • turbolinks:load時点:永続する要素も新しいbody内部へ移動が完了して、それがdocument.bodyになっている

実際に何かしらのウィジェットを渡り歩かせるには、JavaScriptでイベントを拾って、以下のような流れで動かすことになると思います。

  • turbolinks:before-renderの段階で新規マウントしようとしたときには、すでに永続的なマウントが行われていればスルーする
  • すでに永続的にセットされたものについては、
    • turbolinks:before-rendere.data.newBodyもチェックして、新しいHTMLに存在しなければアンマウントする
    • ウィジェットから<body>を読み取ってなにか処理を行うような場合、turbolinks:renderで正しい<body>に入ったところで処理を行わせる
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1