『わんどの写真部! ~ 商用フリー・クレジット表記不要の高解像度写真素材サイト』なるサイトを運営しておりまして、先ごろより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して確かめてみてください、…っていう新手のステマじゃありません。念のため。