『わんどの写真部! ~ 商用フリー・クレジット表記不要の高解像度写真素材サイト』なるサイトを運営しておりまして、先ごろよりpushState&popStateと、Facebookの「いいね!」、Google+1ボタンに対応させる小改造を行ってました。
Ajaxで写真を動的に遷移するのですが、写真ごとにいいね!と+1が欲しいので、遷移したタイミングでボタンを手動でリセットする必要がある、さあ、どうしよう、というのが今回のお題です。
Facebookのほうは、こちらの記事にあったんですが、Googleのを日本語で解説してるサイトは見つからず。仕方ないので、素直に英語の公式ドキュメントあたってみました。
plusone.jsを読み込む
+1 ボタンを動的に表示させる方法はいくつかあるようですが、諸々勘案したところ、今回の条件にマッチするのは、Explicit renderというヤツのようで、その紹介です。
まず、基本スクリプトを読み込みます。<script type="text/javascript" src="https://apis.google.com/js/plusone.js"> {'lang': 'ja', 'parsetags': 'explicit'} </script>
とりあえず<head>タグ内に配置しておけば安全でしょう。
ボタンに表示される言語(lang)と、ボタンを「明示的に(explicit)レンダリングする」=「動的に生成する」かどうか(parsetags)を、オプションで設定してます。
どうでもいいんですが、VBやってた人は、ここで反応してしまいますね。→Option Explicit
ボタンのコンテナを作成
+1ボタンを表示させたい場所に、コンテナとなるブロックレベル要素を記述します。
<div id="plusone-div"></div>
などと、一応id属性を付けといてください。
ボタンの実体をレンダリングする
いよいよ+1ボタンを生成するコードを記述します。
今回の場合だと、最初の写真ページが表示された段階で一度ボタンを生成しますので、windowのloadイベントかなんかに記述します。
↑SyntaxHighliterの仕様で、コーテーションが変なヤツになってます。コピペの際は、通常のものに修正してください。最初の引数でコンテナを指定します。idで指定するならその文字列を書けばいいのですが、ドキュメントにSpecify either the ID of the container (string) or the DOM element itself.
とありますから、DOMオブジェクトそのものをここにいれてもいいようです。jQueryなら$(‘hoge’)[0]とかですか。
二つ目の引数は各種のパラメーターです。ドキュメントの「+1 tag attributes」の項を参考にします。せっかくなんで、主な項目だけ日本語で抜き出してみます。正確性は保証できませんが…。
属性の名前 | 値 | デフォルト値 | 詳細 |
---|---|---|---|
href | (+1させたいページのURL) | (現在のページのURL) | 私には英語がむずかしくてよくわかりませんが、他のページへの+1ボタンを設置するなら、gapi.plus.renderを使え、その際は、この属性を必ず指定せよ、ということのようです。↓下で解説します。 |
size | small medium standard tall |
standard | +1ボタンのサイズ。詳しくは、ここを参照。 |
annotation | none bubble inline |
bubble |
アノテーション(+1の数や、簡単なインフォメーションなどの表示)をどうするか。
|
これだけあれば十分でしょう(汗)。ほかにも、width、align、expandToなどの配置系や、コールバック、吹き出しのホバーイベントなどのハンドラもあるようです。
ここで、どうしてExplicit render、つまりgapi.plus.renderを呼び出す方法を選択したのかが分かります。pushStateとは、「別のページのコンテンツを、現在のページに動的に読み込ませる」ことにほかならないわけですから、ボタンには別のページのURLを設定する、という体になる、というわけです。
ボタンのURLを変更する
で、今回の本題なのですが、これがいたってシンプル。要は、ボタンをレンダリングしなおす、つまり、もう一度gapi.plusone.renderを発火させるだけです。もちろんパラメーターのhrefは、変更先のURLにセット、そのほかのパラメータも、再度記述します。
まとめ
以上をふまえて、HTMLのアウトラインの例を示します。本来は、これにpopState処理なども追加する必要がありますが、割愛します。
<!DOCTYPE html> <html lang="ja"> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript" src="https://apis.google.com/js/plusone.js"> {'lang': 'ja', 'parsetags': 'explicit'} </script> <script> function update(index, is_first_time){ $('#image-container').empty().append( $('<img />').attr('src', 'images/' + index + '.jpg') ); if(!is_first_time) window.history.pushState(null, null, index + '.html'); gapi.plusone.render('plusone-div', { 'href': window.location.href, 'size': 'tall', 'annotation': 'inline' }); }; $(window).load(function(){ $('#links a').click(function(){ update($(this).text(), false); return false; }); var current = window.location.pathname; current = current.substring(current.lastIndexOf('/') + 1,current.length); current = current.substring(0, current.indexOf('.')); update(current, true); }); </script> </head> <body> <div id="image-container"> </div> <div id="links" style="font-size: 150%; margin: 1em 0"> <a href="1.html">1</a> <a href="2.html">2</a> <a href="3.html">3</a> </div> <div id="plusone-div"></div> </body> </html>
これを「1.html」として設置したとすると、同じディレクトリに、以下のような.htaccessを置き、
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*) 1.html [L] </IfModule>
さらに同ディレクトリに「images」ディレクトリを設置して、中に「1.jpg」「2.jpg」「3.jpg」を置き、最初の「1.html」、または、「2.html」「3.html」にアクセスすると動作します。
サンプルをこちらに置いておきますので、実際に+1して確かめてみてください、…っていう新手のステマじゃありません。念のため。