という話

技術ブログにしたい

複数のソーシャルボタンを設置し動的に呼び出す

サイトシェア用と記事シェア用に、同じ種類のソーシャルボタンを置くことになった時のメモ。

ソーシャルボタンは一つ置くだけでかなりレンダリングに時間がかかるので、記事シェア用は静的に設置し、サイトシェア用は動的に呼び出すようにした。

動的に呼び出すのはTwitter,Facebook,Google,はてブの4つ。


まずは普通に記事シェア用のボタン群を各SNSの説明に書かれている通りに設置する

<!-- twitter -->
<a href="https://twitter.com/share" class="twitter-share-button" data-lang="ja">ツイート</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>

<!-- facebook -->
<div id="fb-root"></div>
<script>(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/ja_JP/all.js#xfbml=1&appId=YOUR APP ID";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
<div class="fb-like" data-layout="button_count" data-action="like" data-show-faces="true" data-share="false"></div>

<!-- google -->
<div class="g-plusone" data-annotation="inline" data-width="300"></div>

<script type="text/javascript">
  window.___gcfg = {lang: 'ja'};

  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/platform.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
</script>

<!-- はてブ -->
<a href="http://b.hatena.ne.jp/entry/" class="hatena-bookmark-button" data-hatena-bookmark-layout="standard-balloon" data-hatena-bookmark-lang="ja" title="このエントリーをはてなブックマークに追加"><img src="http://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="http://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script>

これで記事シェア用ボタンは表示できた。

これをこのままコピーしてJSで後から追加して完成!
・・・なんて上手くは行きません:-(

それをすると「同じスクリプトがもう読み込まれてるよ!」とか起こられてうまく表示されない or 上手くシェア出来ない状態になる。
なので、既に呼び出し済みのスクリプトを利用してサイト用のボタンを表示する。

setTimeout(function()
{
  //twitter SDK
  if (typeof twttr != 'undefined')
  {
    twttr.widgets.load();
  }
  else
  {
    !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.async=true;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');
  }

  // facebook SDK
  if (typeof FB != 'undefined')
  {
    FB.XFBML.parse();
  }
  else
  {
    (function(d, s, id) {
      var js, fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) return;
      js = d.createElement(s); js.id = id;
      js.src = "//connect.facebook.net/ja_JP/all.js#xfbml=1&appId=YOUR APP ID";
      fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));
  }

  // google SDK
  if (typeof gapi != 'undefined')
  {
    gapi.plusone.render('target-dom-id', {'href': location.href, 'size': 'medium'});
  }
  else
  {
    window.___gcfg = {lang: 'ja'};
    (function() {
      var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
      po.src = 'https://apis.google.com/js/platform.js';
      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
    })();
  }
}, 5000);


setTimeoutで遅延読み込みさせます。5秒なのに理由はありませんテキトーです。
ただ動的に呼び出すだけなら

twttr.widgets.load();
FB.XFBML.parse();
gapi.plusone.render('target-dom-id', {'href': location.href, 'size': 'medium'}); // target-dom-idは設置する場所のID

上記の3行だけで大丈夫です。
今回は記事ページ以外は静的に設置されたボタンが無いので、それ以外のページではSDKを読み込む必要があったためこのような形になっています。
はてブの呼び出しが無いですが、スクリプトタグを除いた

<a href="http://b.hatena.ne.jp/entry/" class="hatena-bookmark-button" data-hatena-bookmark-layout="standard-balloon" data-hatena-bookmark-lang="ja" title="このエントリーをはてなブックマークに追加"><img src="http://b.st-hatena.com/images/entry-button/button-only@2x.png" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border: none;" /></a>

を、記述するだけで複数でも、動的に追加してもちゃんと表示されました。
はてブさん優秀っすね!(ステマ臭)


以下のページを参考にしました
Ajax+pushStateでページ遷移したときにFacebookプラグインを更新する方法 : Sensebahn
Google+1ボタンの、+1先のURLを動的に変更する | わんどのweb