ソーシャルメディアへの対応 第1回 ツイートボタンの実装

この記事ではさまざまなソーシャルメディアのウィジェットのうち、ツイートボタンの実装の詳細を解説します。外部のサービスを利用するのですから、仕様やAPIに対する理解を深める必要があります。

発行

著者 高津戸 壮 テクニカルディレクター
ソーシャルメディアへの対応 シリーズの記事一覧

はじめに

このシリーズでは、Twitterのツイートボタンや、Facebookのいいねボタンなど、各種ソーシャルメディアが用意するウィジェット、OGPの設定などについて、実装方法や概要をまとめてみます。

このシリーズで紹介するサンプルは次のリポジトリにまとめてあります。併せて、参照してください。

ソーシャルメディアへの対応リポジトリ

なお、本シリーズの内容は、2015年1月時点のものです。各サービスの仕様は、随時アップデートされる可能性があるため、新しい機能や、すでに使えない機能がこの解説の中に含まれているかもしれません。注意してください。

各種ソーシャルメディアとの付き合い方

筆者は、受託案件を手がけることが多いため、ツイートボタンやいいねボタンを、毎回のように配置しています。依頼する側からすると、「どのサイトにもついてるアレ、付けておいてよ」という感覚なのかもしれません。

しかし、これらのウィジェットや、各ソーシャルメディアに表示させたい情報の設定方法は、Webサービスごとに異なる上、実装のためにはいろいろとコンテンツ(テキストや画像など)を準備してもらわないとなりません。

そのためには、実装者として正しく仕様を理解する必要があるのですが、この仕様というもの、Webサービスごとに独自に決めて作られているだけであり、アップデートも頻繁に行われるため、昨日ページに実装した内容は、今日はもう有効でないという可能性も十分にあります。

また、ツイートボタンなどのウィジェット(この記事ではソーシャルメディアのボタン類を総称して、ウィジェットと呼ぶことにします)は、各Webサービスが用意したJavaScriptファイルを読み込み、そのスクリプトが実行され、ページにウィジェットを表現する要素が追加されるのが、一般的なパターンです。

ウィジェットの中には、小さいiframeが配置される実装となっているものも多く見受けられます。そのような実装方法ゆえに、これらウィジェットのデザインは、あまり自由に変更できません。

自由にデザインを変更したいわけではないにせよ、縦の揃え位置、高さ、横幅などを自由にできない場合もあります。ツイートボタンやいいねボタンを配置するだけでも、デザイン的に考慮しなければならないことが、いろいろとあります。

このように、当たり前のように使われていながら、実際は実装に手間がかかることが多い各種ソーシャルメディアへの対応について解説していきます。

このシリーズで取り扱う内容

このシリーズでは、次の内容を取り扱います。Twitter、Facebook、Google+、LINEの4メディアをカバーする予定です。

なお、筆者は、各種ソーシャルウィジェットへの対応が手間であったため、それぞれのウィジェットについて、手軽にセットアップできるよう、jQueryプラグインを作り、使い回しています。以下のリポジトリにありますので、気になる方はお試しいただければと思います。

Twitter : Tweet Buttonの実装例

まずはTwitterのツイートボタンです。ツイートボタンのドキュメント、ツイートボタンの作成画面は以下にあります。

まずはサンプルを見てみます。といっても、ツイートボタン作成画面で生成されたコードを貼り付けているだけですが。

<a
  href="https://twitter.com/share"
  class="twitter-share-button"
  data-via="codegrid"
>Tweet</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>

ツイートボタンの作成ページ上でコードを作り、貼り付けるだけでできるため、非常に手軽です。2015年1月現在、リンクシェアボタン、フォローボタン、ハッシュタグボタン、メンションボタンの4つが用意されているようです。これらを並べたデモを見てみます。

<a
  href="https://twitter.com/share"
  class="twitter-share-button"
  data-via="codegrid"
>
  Tweet
</a>

<a
  href="https://twitter.com/codegrid"
  class="twitter-follow-button"
  data-show-count="false"
>
  Follow @codegrid
</a>

<a
  href="https://twitter.com/intent/tweet?button_hashtag=TwitterStories"
  class="twitter-hashtag-button"
  data-related="codegrid"
>
  Tweet #TwitterStories
</a>

<a
  href="https://twitter.com/intent/tweet?screen_name=codegrid"
  class="twitter-mention-button"
  data-related="codegrid"
>
  Tweet to @codegrid
</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>

ソースコードを見てもわかるとおり、script要素を何度も書く必要はありません。どのツイートボタンを選んでも同じものが出力されるだけであり、一度書いておくだけで用は足ります。

各ボタンについて、カスタマイズできる項目は、data属性(data-)として指定します。Twitterが用意したスクリプトが、各data属性値から判断し、よしなに処理してくれます。

script要素の中身

次に、コード中のscript要素が何をしてくれているのか、もう少し突っ込んでみてみます。

jsbeautifier.orgなどで、このコードを整形すると、次のようになります。

! 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');

このコードは、ざっくりいうと以下の処理を行っています。

  • 現在のlocationを見て、プロトコルがhttphttpsか判断する
  • もしidtwitter-wjsである要素があったら何もしない
  • 新しくscript要素を作る
  • そのidtwitter-wjsを指定
  • そのsrcに、プロトコルに合わせたwidgets.jsへのパスを指定
  • 作ったscript要素をページに突っ込む

一度このコードが実行されていれば、すでにページ内にidtwittr-wjsである要素が存在しているはずですので、実質何も起こりません。なので、一度だけこのコードを実行すればよいのです。

このwidgets.jsの処理内容としては、ページ読み込み後、ページ内に存在するツイートボタンの元となる要素を探し出し、それぞれについてツイートボタンの機能を割り当てる役割をしているようです。このようにして、ページ内のツイートボタンが作られます。

ツイートボタンが重い理由

では、このツイートボタンとやらは具体的にはどのようなものなのか、Chromeのデベロッパーツールで覗いてみると……

大きい画像

これらのボタン一つ一つが、iframeであることがわかります。

これらのボタンがiframeで作られている理由としては、ツイートボタンが配置されたページとの干渉を避けるためという点が大きいものと予想されます。

仮にこれらのツイートボタンがiframeではなく、divなどの要素で構成されていた場合、文字や画像のサイズをはじめとしたさまざまなスタイルが、そのページで読み込んでいるスタイルシートの影響を受けてしまうはずです。

iframeにしておけば、ツイートボタンが配置されたページのスタイルやJavaScriptの影響を受けません。

ツイートボタンのレイアウトが崩れず、嬉しくはあるのですが、このようにボタンごとにiframeが作られるため、それぞれのボタンについて、ブラウザは、ひとつのページをレンダリングするに等しい処理を行う必要があります。

ページにたくさんのツイートボタンを配置したいと思った場合、あわやブラウザがフリーズしかけるほどに重い処理になってしまうことがありえますので、注意したほうがよいでしょう。

業務上必要ですから、こんな記事を書いてはいるものの、筆者の個人的な思いとしては、ソーシャルメディア系のウィジェットは重いので大嫌いです。

幅が広いツイートボタン

ツイートボタンが作られたあと、各ボタンの幅を確認するため、iframeに3pxのボーダーを付けてみます。

これを見てわかるとおり、ツイート件数が付いたボタンは、かなり余裕を持って幅が確保されていることがわかります。右の吹き出し内のカウント桁数による違いをカバーするため、このように余裕のある幅が取られているようです。カウントの桁数に合わせ、ツイートボタンの幅にピッタリになるように、この幅を調節してほしいものですが、残念ながらそのようなことはできません*。

*注:カウント数の非表示

data-count="none"を指定し、カウント数を表示させなければ、iframeの幅はボタン幅ピッタリになります。

もし右の余白を詰めたければ、ツイートボタンの外側にひとつdivなどを配置し、そのwidthheightを固定するなどの方法で、無理矢理調節する以外に方法はなさそうです。

ただし、このツイートボタンの領域は、Twitterが用意したスクリプトにより生成される部分であるため、いつ幅や高さが変わるか、まったくコントロールできない状態です。

このツイートボタンのようなウィジェットは、いつレイアウトが変更されるか、仕様が変わったために動作おかしくなるかわからないという一面があります(影響が大きいため、そうそうレイアウトが変更されたりはしないことは想像できますが)。縦にボタンを並べたりして、右側に付く余白が気にならないようにする必要があるかもしれません。

ダイナミックにツイートボタンを作成する

ページに配置されたツイートボタンは、ページ読み込み完了時に一斉に作られます。しかし、ページの読み込みが完了したあとからJavaScriptによって追加されたコンテンツについても、ツイートボタンを作りたい場合があります。

次のサンプルでは「ボタン追加」を押すと、ツイートボタンの元となる要素をページに追加しますが、このままではツイートボタンになりません。

この場合、JavaScriptは次のようになっています。

$(function() {
  var $body = $('body');
  var src = '<a href="https://twitter.com/share" class="twitter-share-button" data-via="codegrid">Tweet</a> ';
  $('#adder').click(function() {
    $body.append(src);
  });
});

次のサンプルでは、「ツイートボタン化」ボタンを追加しました。まず「ボタン追加」を押してから、この「ツイートボタン化」を押すと、twttr.widgets.load();が実行され、追加したコンテンツにおいて、対象となる要素群がツイートボタン化されます。

このように、あとから追加された要素についても、ダイナミックにツイートボタンを作るためには、twttr.widgets.load();を実行してやるとよいようです。このtwttrオブジェクトは、widgets.jsを読み込むと作られます。

$(function() {
  var $body = $('body');
  var src = '<a href="https://twitter.com/share" class="twitter-share-button" data-via="codegrid">Tweet</a> ';
  $('#adder').click(function() {
    $body.append(src);
  });
  $('#tweetify').click(function() {
    twttr.widgets.load();
  });
});

このようにすれば、あとからページに追加されたコンテンツについても、ツイートボタンを付加することができます。より詳しい情報については、次のTwitter公式ドキュメントを参照して下さい。

Factory Functionsを利用する

このほか、Twitterの公式ドキュメントには、ダイナミックにツイートボタンを作成する方法が、もうひとつ紹介されています。Factory Functionsとして紹介されている方法を用いれば、任意の要素を指定することで、その要素内にボタンを作成します。以下にサンプルを用意しました。

HTMLとJavaScriptはそれぞれ次のようになっています。

<div id="button"></div>
<script src="https://platform.twitter.com/widgets.js"></script>
twttr.ready(function() {
  twttr.widgets.createShareButton(
    location.href,
    document.getElementById('button'),
    {
      lang: 'ja',
      text: 'Welcome to CodeGrid!!'
    }
  ).then(function (el) {
    console.log("Button created.")
  });
});

JavaScriptでイチからボタンを作成するには、もっとも融通のきく方法であるといえそうです。より詳細な情報については、次のドキュメントを参照して下さい。

Web Intentsを利用する

ドキュメントで、Web Intentsとして紹介されている方法を用いれば、ツイートボタンを作成せずとも、ツイートやリツイートをさせることができます。その仕組みは非常に単純で、特定のURLにGETパラメータを渡して開くだけです。

次のサンプルがWeb Intentsを利用したものです。リンクをクリックするだけで、特定のツイートのツイートや、リツイートなどを確認する画面に遷移します。

HTMLは次のようになっています。

<ul>
<li><a href="https://twitter.com/intent/tweet" target="_blank">Tweet</a></li>
<li><a href="https://twitter.com/intent/tweet?in_reply_to=500051068265308160" target="_blank">Reply</a></li>
<li><a href="https://twitter.com/intent/retweet?tweet_id=500051068265308160" target="_blank">Retweet</a></li>
<li><a href="https://twitter.com/intent/favorite?tweet_id=500051068265308160" target="_blank">Favorite</a></li>
</ul>

Web Intentsは、https://twitter.com/intent/から始まるURLにアクセスすることで、Tweet、Reply、Retweet、Favoriteを行う画面を提供します。上記サンプルでは、この4種類の画面へのリンクを並べています。指定できるパラメータなどの詳細については、次のドキュメントを参照してください。

Web Intentsのポップアップ

widgets.jsを読み込めば、Web Intentsを利用したリンクすべてについて、単純にリンクを開く代わりに、コンテンツにちょうどいいサイズでwindow.openしてくれます。次にサンプルを用意しました。各a要素は、ひとつ前のサンプルとまったく同じです。

HTMLは以下のようになっています。

<ul>
<li><a href="https://twitter.com/intent/tweet" target="_blank">Tweet</a></li>
<li><a href="https://twitter.com/intent/tweet?in_reply_to=500051068265308160" target="_blank">Reply</a></li>
<li><a href="https://twitter.com/intent/retweet?tweet_id=500051068265308160" target="_blank">Retweet</a></li>
<li><a href="https://twitter.com/intent/favorite?tweet_id=500051068265308160" target="_blank">Favorite</a></li>
</ul>

<script type="text/javascript" async src="//platform.twitter.com/widgets.js"></script>

widget.js内では、documentclickイベントを監視し、jQueryのdelegate*のような仕組みでa要素のクリックをチェックしています。このため、新しくページ上にWeb Intentのリンクが追加されても、同様に動作するようになっています。

*注:delegate

delegateに関しては「実践、jQuery:.on()と.off()を使いこなす 1」の「デリゲートを利用したイベント設定」などを参照してください。

Web Intentsを利用するメリットとしては、動作が軽いことがまず挙げられるでしょう。Web Intentsは、ほとんどただのリンクであり、ツイートボタンのようにiframeが作られません。このため、ツイートボタンと比較すると、処理負荷は圧倒的に低いです。

また、自由なデザインでボタンを作成できるという点もメリットといえそうです。用意されたツイートボタンでは、サイズの変更程度のデザイン変更しか行えません。一方、Web Intentsを利用した場合は、URLさえ開ければいいので、例えばFlashで作られたコンテンツの内部からツイートのポップアップを出すというような用途にも使えそうです。

デメリットとして挙げられるのは、まず、ツイートボタンに付いているツイート件数表示ができない点です。件数表示を行うAPIを、Twitterは提供していません。件数表示ができるのは、Twitterが用意したツイートボタンを使った場合に限られます。

このほかにデメリットといえそうなのは、前述したツイートボタンのデザインがほぼ固定されていることの裏返しで、自らツイートボタンをデザインしなければならないという点でしょうか。自由度が高いということではあるのですが、何も用意しなければただのテキストリンクです。処理負荷が気にならないような状況であれば、用意されているツイートボタンを使ったほうがお手軽というケースも多いでしょう。

要件に応じ、ツイートボタンと使い分けるとよいのではないでしょうか。

まとめ

今回は、Twitterのツイートボタンの実装方法を解説しました。たかがツイートボタンとはいえども、その実態は、外部サービスが提供する、こちらでコントロールできる範囲が限られた機能を利用することになります。

ですから、複数のウィジェットを利用したり、ほかのJavaScriptと組み合わせるような必要がある場合、開発者としては、その実装詳細、用意されているAPIについて、ある程度正確に把握しておく必要があるでしょう。

次回は、Facebookの各種ウィジェットについて解説します。