Turbolinksへの対応(Facebook,Twitter,はてブ,LINE)
前回、infinite scrollとTurbolinksの対応を書いたのですが、いくつかのJavaScriptライブラリでTurbolinksとの関係に悩まされます。
特にソーシャルボタンの設置にはJavaScriptを使用していることが多く、Turbolinksはほぼ確実にこれらに影響を及ぼします。
つまり、そのままでは動きません。
有志が「Turbolinks Compatibility」ということで、対応を整理してくれています。
http://reed.github.io/turbolinks-compatibility/
これは便利!
Facebook、Twitter、Google関連サービス(Google+、AdSense、Analytics)といった海外の主要サービスはかなり対応しています。
そのままコピペして使えちゃいます。
(…Pocketがないなぁ)
で、日系のサービスが全然ありません。
よく使うのははてなブックマークとLINEでしょうか。
<a href="http://b.hatena.ne.jp/entry/" class="hatena-bookmark-button" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="このエントリーをはてなブックマークに追加"> <img src="https://b.st-hatena.com/images/entry-button/button-only@2x.png" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border: none;" /> </a> <script type="text/javascript" src="https://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script>
はてなブックマークボタンのコードは普通はこうですね。
最後のスクリプトタグは他のサービス同様、一回読みこめばいいのでheadタグにいれておきましょう。
Turbolinksで遷移すると再度ロードしないので、高速化の恩恵が受けられます。
はてなブックマークのいいところは定期的に”hatena-bookmark-button”クラスのついた aタグを監視していて、見つけたらボタンに変換してくれます。
だから、TurbolinksでもAJAXでもPJAXでもHTMLをロードしてbodyタグにappendすれば、すぐにはてなブックマークボタンになります。
気をつけなければいけないのは、はてなブックマーク対象のURLを明示的に指定しない場合です。
a タグの href の http://b.hatena.ne.jp/entry/ の後にURLを指定することもできるのですが、指定しなかった場合は、そのページのURLになります。
通常はwindow.location.hrefで取得できるURLを使用するのですが、カノニカルタグ(<link rel=”canonical”>)があったら、そちらのURLを見るのです。
Turbolinksはカノニカルタグやメタタグは変更しません。
変更するのはtitleタグだけです。
カノニカルタグを使用している場合は、はてなブックマーク対象のURLを明示的に指定するようにしましょう。
これはなかなか気づきませんね。
また、戻るボタンを押したときにも問題が発生します。
a タグはiframeのボタンに変換されているのですが(戻っただけなので)、見えなくなっています。
こちらは見えなくなるのですぐ気づくと思います。
戻るボタンを押したときにだけ起きるイベントは page:restore だと前回学びました。
$(document).on "page:restore", -> $('.hatena-bookmark-button-frame') .replaceWith '<a href="//b.hatena.ne.jp/entry/' + encodeURIComponent(window.location.href) + '" class="hatena-bookmark-button" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="このエントリーをはてなブックマークに追加"><img src="//b.hatena.ne.jp/images/entry-button/button-only@2x.gif" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border:none;"/></a>'
やっていることは単純で、iframeに変わったボタンを元に戻しているだけです。
元のHTMLに戻ったら、はてな提供のスクリプトが勝手にiframeのボタンに再変換してくれます。
はてなブックマークでのポイント
- カノニカルタグを使用している場合は対象URLを明示的に指定する
- page:restore イベントでiframeに変換済みのボタンを aタグに戻してあげる
LINEでのシェアボタンは通常はこのようになります。
<span> <script type="text/javascript" src="//media.line.me/js/line-button.js?v=20140411" ></script> <script type="text/javascript"> new media_line_me.LineButton({"pc":false,"lang":"ja","type":"e"}); </script> </span>
LINEが他のと違うのは、ある特定のタグを置き換えるのではなく、scriptのある位置にをタグを作って挿入するという方式だということです。
その位置にscriptがないといけないので、やっかいです。
このままでも動くのですが、悪影響を及ぼさないように、scriptはbodyから排除したいものです。
LINEはscriptで出力した結果がすごく単純です。
だからはじめから結果を書いてしまいましょう。
<a href="http://line.me/R/msg/text/?#{URI.escape("#{title} #{url}", Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}"> <img src="//media.line.me/img/button/ja/36x60.png",width="36" height="60" alt="LINEで送る"> </a>
これはrailsで出力した場合で、titleとurlを入れてエスケープしています。
Turbolinksのイベントを駆使して、javascriptでやっていもいいと思います。
LINEでのポイント
- LINE提供のスクリプトを使用せず、はじめから最終的なボタンの形式でHTMLに出力する