ソーシャルサービス固有のシェアのボタンって表示が重たいと感じる時はないでしょうか?
特にFacebookのボタンとか。シェアボタンが表示されないので、それ以降のページが表示されないなんてことも結構あります。
今回は、そんな不満を解消すべく、JavaScriptのAjaxを使用した自作のバルーンボタンの作り方を紹介したいと思います。非同期処理を使用することで、ページが読み込まれてからシェア数を取得しに行くので、ページ表示スピードが体感的にかなり速くなります。
最終目標はこんなボタンになります。
今回は、これまでいろいろ調べてきたことのまとめの記事となり、コピペで使えるようになっています。ですので、コードに書かれている中身とかは深く考えず、コピペに専念すれば、10分もかからずにカスタマイズできるのではないかと思います。
photo by Trevor Bexon
目次
自作バルーンボタン作成の主な手順
自作ボタンの作成に必要となる主な手順は以下です。
- アイコンフォントファイルなどの準備
- 必要なライブラリファイルの呼び出し(コピペ)
- JavaScriptファイルの作成(コピペ)
- functions.phpファイルに関数の追加(コピペ)
- ボタン用テンプレートファイルの作成(コピペ)
- バルーンシェアボタンのスタイル設定(コピペ)
- header.phpファイルからJavaScriptの関数を呼び出す(コピペ)
とこんな感じになります。ほとんどコピペなので、カスタマイズはそこまで難しくないと思います。
一応どんなテーマにもカスタマイズ出来るので、今回は「Twenty Ten」テーマに取り付けてみたいと思います。
アイコンフォントファイルの準備
まずは、シェアボタンに各種ソーシャルボタンのアイコンを表示させたいので、アイコンファイルをダウンロードします。
まずは以下から、アイコンフォントファイルをダウンロードして解凍してください。
[wpdm_file id=5 title=”true” desc=”true” ]
作成されたicomoonフォルダを、テーマファイルフォルダ直下にコピペしてください。
必要なライブラリファイルの呼び出し
次に、header.phpの<head></head>内に必要なライブラリファイルを呼び出します。
<!-- IcoMoonウェブアイコンフォントの呼び出し --> <link rel="stylesheet" href="<?php echo get_template_directory_uri(); ?>/icomoon/style.css"> <!--Font Awesomeの読み込み--> <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet"> <!--jQueryが読み込まれてない場合はjQueryライブラリの呼び出し--> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
今回、Font Awesomeと、jQueryは、WEB上にホストされたものを使用しましたが、ダウンロードしてローカルから呼び出してもOKです。
JavaScriptファイルの作成
今回は、バルーンボタンの吹き出し部分にjQueryのAjaxにより非同期でシェア数を読み込みます。
そのためのJavaScript関数をjavascript.jsファイルに作成します。(ファイル名は何でも良いです。テーマに最初からあるファイルと名前がかぶる場合は変更してください。)
現在は、以下のような手段で、JavaScriptからPHPファイルを呼び出して、PHPでシェア数を取得する必要があるかもしれません。
Simplicityでは、以下のように取得しています。
JavaScriptの関数
https://github.com/yhira/simplicity2/blob/master/javascript.js
Google+用のシェア数取得ファイル
https://github.com/yhira/simplicity2/blob/master/lib/fetch-google-plus.php
ポケット用のシェア数取得ファイル
https://github.com/yhira/simplicity2/blob/master/lib/fetch-pocket.php
シェア数取得用関数
https://github.com/yhira/simplicity2/blob/master/lib/sns.php
// Twitterのシェア数を取得 function get_social_count_twitter(url, selector) { jQuery.ajax({ url:'http://urls.api.twitter.com/1/urls/count.json', dataType:'jsonp', data:{ url:url }, success:function(res){ jQuery( selector ).text( res.count || 0 ); }, error:function(){ jQuery( selector ).text('0'); } }); } function get_social_count_facebook(url, selector) { jQuery.ajax({ url:'https://graph.facebook.com/', dataType:'jsonp', timeout: 10000, //10sec data:{ id:url } }).done(function(res){ if ( res.share && res.share.share_count ) { jQuery( selector ).text( res.share.share_count ); } else { jQuery( selector ).text( 0 ); } }).fail(function(){ jQuery( selector ).text('0'); }); } //Google+のシェア数を取得 function get_social_count_googleplus(url, selector) { jQuery.ajax({ type: "get", dataType: "xml", url: "http://query.yahooapis.com/v1/public/yql", data: { q: "SELECT content FROM data.headers WHERE url='https://plusone.google.com/_/+1/fastbutton?hl=ja&url=" + url + "' and ua='#Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36'", format: "xml", env: "http://datatables.org/alltables.env" }, success: function (data) { var content = jQuery(data).find("content").text(); var match = content.match(/window\.__SSR[\s*]=[\s*]{c:[\s*](\d+)/i); var count = (match != null) ? match[1] : 0; jQuery( selector ).text(count); } }); } //はてなブックマークではてブ勝を取得 function get_social_count_hatebu(url, selector) { jQuery.ajax({ url:'http://api.b.st-hatena.com/entry.count?callback=?', dataType:'jsonp', data:{ url:url }, success:function(res){ jQuery( selector ).text( res || 0 ); }, error:function(){ jQuery( selector ).text('0'); } }); } //ポケットのストック数を取得 function get_social_count_pocket(url, selector) { jQuery.ajax({ type: "get", dataType: "xml", url: "http://query.yahooapis.com/v1/public/yql", data: { q: "SELECT content FROM data.headers WHERE url='https://widgets.getpocket.com/v1/button?label=pocket&count=vertical&v=1&url=" + url + "' and ua='#Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36'", format: "xml", env: "http://datatables.org/alltables.env" }, success: function (data) { var content = jQuery(data).find("content").text(); var match = content.match(/<em id="cnt">(\d+)<\/em>/i); var count = (match != null) ? match[1] : 0; jQuery( selector ).text(count); } }); }
※2016年8月19日のFacebookの仕様変更に対応
作成したファイルは、テーマファイル直下に置いてください。
これらの関数の詳細は、以下の記事に書かれています。
functions.phpファイルに必要な関数を追記
次に、後でテンプレートファイルで使用する関数をfunctions.phpファイルに追記しておきます。
//はてブするときに使用するエンコードしたタイトル function get_encoded_title($title){ return urlencode(mb_convert_encoding($title, "UTF-8")); }
シェアボタン用テンプレートファイルの作成
次に、「sns-buttons-balloon.php」とでも名前をつけて、テーマフォルダ内にファイルを作成し、以下のコードをコピペしてください。
<div id="sns-buttons" class="sns-buttons-pc"> <ul class="snsb snsb-balloon"> <li class="balloon-btn twitter-balloon-btn"> <span class="balloon-btn-set"> <span class="arrow-box"> <a href="https://twitter.com/search?q=<?php echo urlencode(get_the_permalink()); ?>" target="blank" class="arrow-box-link twitter-arrow-box-link" rel="nofollow"> <span class="social-count twitter-count"><i class="fa fa-spinner fa-spin"></i></span> </a> </span> <a href="http://twitter.com/share?text=<?php the_title() ?>&url=<?php the_permalink() ?>" target="blank" class="balloon-btn-link twitter-balloon-btn-link" rel="nofollow"> <i class="icon-twitter"></i> </a> </span> </li> <li class="balloon-btn facebook-balloon-btn"> <span class="balloon-btn-set"> <span class="arrow-box"> <a href="https://www.facebook.com/sharer/sharer.php?u=<?php the_permalink() ?>&t=<?php the_title() ?>" target="blank" class="arrow-box-link facebook-arrow-box-link" rel="nofollow"> <span class="social-count facebook-count"><i class="fa fa-spinner fa-spin"></i></span> </a> </span> <a href="https://www.facebook.com/sharer/sharer.php?u=<?php the_permalink() ?>&t=<?php the_title() ?>" target="blank" class="balloon-btn-link facebook-balloon-btn-link" rel="nofollow"> <i class="icon-facebook"></i> </a> </span> </li> <li class="balloon-btn googleplus-balloon-btn"> <span class="balloon-btn-set"> <span class="arrow-box"> <a href="https://plus.google.com/share?url=<?php echo rawurlencode(get_permalink($post->ID)) ?>" onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;" target="blank" class="arrow-box-link googleplus-arrow-box-link" rel="nofollow"> <span class="googleplus-count"><i class="fa fa-spinner fa-spin"></i></span> </a> </span> <a href="https://plus.google.com/share?url=<?php echo rawurlencode(get_permalink($post->ID)) ?>" onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;" target="blank" class="balloon-btn-link googleplus-balloon-btn-link" rel="nofollow"> <i class="icon-googleplus"></i> </a> </span> </li> <li class="balloon-btn hatena-balloon-btn"> <span class="balloon-btn-set"> <span class="arrow-box"> <a href="http://b.hatena.ne.jp/entry/<?php the_permalink() ?>" target="blank" class="arrow-box-link hatena-arrow-box-link" rel="nofollow"> <span class="social-count hatebu-count"><i class="fa fa-spinner fa-spin"></i></span> </a> </span> <a href="http://b.hatena.ne.jp/add?mode=confirm&url=<?php the_permalink() ?>&title=<?php echo get_encoded_title( get_the_title() ) ?>" target="blank" class="balloon-btn-link hatena-balloon-btn-link" rel="nofollow"> <i class="icon-hatena"></i> </a> </span> </li> <li class="balloon-btn pocket-balloon-btn"> <span class="balloon-btn-set"> <span class="arrow-box"> <a href="https://getpocket.com/edit?url=<?php the_permalink() ?>" target="blank" class="arrow-box-link pocket-arrow-box-link" rel="nofollow"> <span class="social-count pocket-count"><i class="fa fa-spinner fa-spin"></i></span> </a> </span> <a href="https://getpocket.com/edit?url=<?php the_permalink() ?>" target="blank" class="balloon-btn-link pocket-balloon-btn-link" rel="nofollow"> <i class="icon-pocket"></i> </a> </span> </li> </ul> </div> <div style="clear:both"></div>
それぞれのソーシャルサービスへのリンク方法については、以下の記事に詳しく書いてあります。
あとは、シェアボタンを呼び出したい箇所に、以下のコードを書いてボタンを呼び出します。
<?php get_template_part('sns-buttons-balloon'); ?>
シェアボタンを挿入する位置は、single.phpの本文下あたりが無難かと思います。
この時点で、ブラウザで動作確認してみると、以下のようにな通常リンクリストになっています。
クルクル回っているところは、Font Awesomeの「class=”fa fa-spinner fa-spin”」を使用して、「読み込み中…」の動作を表現しています。
<i class="fa fa-spinner fa-spin"></i>
バルーンシェアボタンのスタイル設定
あとは、style.cssなどに先程設置したシェアボタンテンプレートファイルのスタイルを設定します。
/************************************ ** 自作のバルーンシェアボタン ************************************/ ul.snsb-balloon{ padding:0; margin:20px 0; } ul.snsb-balloon li { float: left; list-style-type: none; margin-right: 8px; } .balloon-btn-set{ display:block; width:60px; height:63px; } .balloon-btn-set a{ display:block; color:#777; font-size:14px; text-decoration:none; } a.arrow-box-link{ font-weight:bold; text-align:center; font-family: Arial; display:block; } a.balloon-btn-link{ border:1px solid #ddd; width:58px; height:20px; line-height:20px; position:relative; top:4px; color:white; border-radius:3px; text-align:center; display:block; } .arrow-box { position: relative; background: #fff; border: 1px solid #bbb; text-align:center; width:58px; height:33px; border-radius:3px; line-height:33px; display:inline-block; } .arrow-box:after, .arrow-box:before { top: 100%; left: 50%; border: solid transparent; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; } .arrow-box:after { border-color: rgba(255, 255, 255, 0); border-top-color: #fff; border-width: 3px; margin-left: -3px; } .arrow-box:before { border-color: rgba(187, 187, 187, 0); border-top-color: #ddd; border-width: 5px; margin-left: -5px; } /************************************ ** Twitterタイプボタン表示CSS ************************************/ a.balloon-btn-link { font-size:16px; font-weight:normal; border:1px solid #bbb; text-decoration:none; background:-moz-linear-gradient( center top, #f9f9f9 5%, #e9e9e9 100% ); background:-ms-linear-gradient( top, #f9f9f9 5%, #e9e9e9 100% ); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#e9e9e9'); background:-webkit-gradient( linear, left top, left bottom, color-stop(5%, #f9f9f9), color-stop(100%, #e9e9e9) ); background-color:#f9f9f9; color:#666666; display:inline-block; text-shadow:1px 1px 0px #ffffff; -webkit-box-shadow:inset 1px 1px 0px 0px #ffffff; -moz-box-shadow:inset 1px 1px 0px 0px #ffffff; box-shadow:inset 1px 1px 0px 0px #ffffff; } a.twitter-balloon-btn-link{color:#55acee;} a.facebook-balloon-btn-link{color:#3c5a99;} a.googleplus-balloon-btn-link{color:#dd4b39;} a.hatena-balloon-btn-link{color:#3c7dd1;} a.pocket-balloon-btn-link{color:#ee4257;} a.line-balloon-btn-link{color:#00c300;} a.evernote-balloon-btn-link{color:#51b125;} a.feedly-balloon-btn-link{color:#87bd33;} a.twitter-balloon-btn-link:hover{color:#55acee;} a.facebook-balloon-btn-link:hover{color:#3c5a99;} a.googleplus-balloon-btn-link:hover{color:#dd4b39;} a.hatena-balloon-btn-link:hover{color:#3c7dd1;} a.pocket-balloon-btn-link:hover{color:#ee4257;} a.line-balloon-btn-link:hover{color:#00c300;} a.evernote-balloon-btn-link:hover{color:#51b125;} a.feedly-balloon-btn-link:hover{color:#87bd33;}
バルーンボタンの作り方については、以下に詳しく書いています。
バルーンについては、以下のジェネレーターを使ってコードを作成し、それを編集しました。
ボタンのグラデーションについては、以下のジェネレーターを利用しました。
この時点で、ブラウザで確認してみると以下のようになっています。
この時点では、まだJavaScript(jQuery)によりシェア数を取得する関数の実行コードを書いていないので、まだFont Awesomeの「読み込み中…」フォントが回っているだけです。
JavaScriptのシェア数取得関数を呼び出す
最後に、header.phpの<head></head>あたり(jQuery呼び出しファイルより下)に、以下のコードを書けば、シェア数の取得動作は完了します。
<script> jQuery(function(){ <!-- 関数はjavascript.jsの中 --> get_social_count_twitter('<?php the_permalink(); ?>', '.twitter-count'); get_social_count_facebook('<?php the_permalink(); ?>', '.facebook-count'); get_social_count_googleplus('<?php the_permalink(); ?>', '.googleplus-count'); get_social_count_hatebu('<?php the_permalink(); ?>', '.hatebu-count'); get_social_count_pocket('<?php the_permalink(); ?>', '.pocket-count'); }); </script>
これですべて設定は完了しました。
動作確認
ブラウザで読み込んで見ると、ページが表示されてから、JavaScriptが非同期的に実行され、それぞれのサービスのシェア数を読み込んでいます。
ページが読み込まれてから、シェア数を取得する時間も結構早いのではないかと思います。(サービスのサーバーの状態にもよる)
おまけ
せっかく縦型のバルーンボタンを作ったんだから、これを機に横型のバルーンボタンも作ってしまいましょう。
とは言っても、先程作成した「sns-buttons-balloon.php」テンプレートをそのまま使うので、また1からバルーンボタンのHTMLを作る必要はありません。
「sns-buttons-balloon.php」中のHTMLのスタイルシートを変更して使用します。
スタイルシート変更用の仕掛けとして「sns-buttons-top.php」というファイルを作成します。それに以下のように書き込みます。
<div id="sns-group-top" class="sns-group sns-group-top"> <?php get_template_part('sns-buttons-balloon'); ?> </div>
先程のテンプレートを、div#sns-group-topのラッパーでくるんでいます。
あとは、single.phpのタイトル下あたりに、以下のように書いて、そのテンプレートファイルを呼び出します。
現時点で、ブラウザで確認してみると、先程と同様のものが表示されています。
あとは、style.cssに横型バルーンボタン用のスタイルを以下のように追記するだけです。
/************************************ ** タイトル下SNSボタン ************************************/ #sns-group-top .balloon-btn-set{ display:block; width:85px; height:22px; margin-bottom:10px; } #sns-group-top ul.snsb-balloon li{ margin-right:8px; } #sns-group-top ul.snsb-balloon .arrow-box{ height:20px; width:50px; line-height:20px; float:right; } #sns-group-top ul.snsb-balloon .arrow-box-link{ line-height:20px; text-align:center; } #sns-group-top ul.snsb-balloon .balloon-btn-link{ top:0; width:28px; float:left; } #sns-group-top .arrow-box { position: relative; background: #fff; border: 1px solid #bbb; } #sns-group-top .arrow-box:after, #sns-group-top .arrow-box:before { right: 100%; top: 50%; border: solid transparent; content: " "; height: 0; width: 0; left:auto; position: absolute; pointer-events: none; } #sns-group-top .arrow-box:after { border-color: rgba(255, 255, 255, 0); border-right-color: #fff; border-width: 3px; margin-top: -3px; } #sns-group-top .arrow-box:before { border-color: rgba(119, 119, 119, 0); border-right-color: #bbb; border-width: 4px; margin-top: -4px; }
すると、先程の縦型のバルーンが、以下のように横型に変わります。
ページをリロードすると、縦型と同じように動作します。
まとめ
今回の方法で、2種類のバルーンボタンを、ほとんどコピペだけで作ることができます。
普段サイトを運営していて、「SNSシェアボタンの読み込みが遅くてページが表示されづらい」「特にFacebook!お前だお前!」なんて具合に普段感じている方に、今回の方法はおすすめです。
すごく素敵なのですが、個別ページだけではなくアーカイブページなどでも表示させたい場合にはどうしたら良いのでしょうか?