「忍者おまとめボタンをファンブログで」の続きです。
「忍者おまとめボタン」はSNSボタンを表示する中では、なかなか速いと思います。
ただ、トップページやアーカイブページに10個も記事があるとさすがに少しもたつく気がします。
原因はdocument.writeです。
SNSボタンの表示箇所があるたびにdocument.writeの描画が行なわれ、そのたびにHTMLのレンダリングが止まります。1記事ページにだけ使うのならば全く気にならない程度なのですが。
画面の描画がすべて終わるのを待ってからSNSボタンの書き込みを行なったらいいのではないか?ということで、addEventListenerとattachEventを使ってソースを書きかえてみました。
ただし、表示箇所が10箇所に分かれるので、DOMでページ内を走査することになります。結果的に途中で待つか、後で待つかの違いだけかもしれません。
今回やりたかったのは、もうひとつの理由があってトップページですべての記事にSNSボタンをつけるとウザい。というのがありました。長い記事ならいいのですが、短い記事の度にボタンが付くのはいかがなものか?
短い中には、「続きを読む」の前までで切れている記事があります。そこで「続きを読む」がある場合はSNSボタンを表示しないが、全文が表示されている場合には表示するというルールを作りました。
そして、今まで「ポチッとボタン自動挿入モジュール」で書き込んでいたランキング投票ボタンも一緒に表示することにしました。
さらに、ボタンの中にはブックマークされた数を表示するものがありますが、複雑になるほど遅くなるという都合上、すべてのボタンは数字を表示しないものにしました。いずれにしてもゼロの連続ではみっともないですし。
entryInfo の修正
前回書き込んだentryInfoの部分を修正します。書き込んでいた<script>から</script>までを完全に削除します。
そして、2つのspanタグのクラス名を下のように変更します。同じクラス名だとどちらにURLが書き込まれていて、どちらにタイトルが書き込まれているかの判別が面倒だからです。
この2つのspanタグにあったstyle="display:none;"は不要です。表示されることなく上書きされて消滅します。
あと、これは変える必要はないのですがninja_onebuttonの名前もsnsbtnに変えました。
結果、修正後は下の通りです。
<div class="entryInfo">
<div class="snsbtn">
<span class="url_hidden">{$BlogEntryPermalinkUrl$}</span>
<span class="title_hidden">{$BlogEntryTitle$}|{$BlogName$}</span>
</div>
投稿者:<a href="{$BlogEntryWriterUrl$}" target="_blank">{$BlogEntryWriterName$}</a>|{$BlogEntryDate format="%H:%M"$}<BlogEntryIfCategory>|<a href="{$BlogEntryCategoryLink$}">{$BlogEntryCategory$}</a></BlogEntryIfCategory><BlogEntryIfAllowComments>|<a href="{$BlogEntryPermalinkUrl$}#commentTitle">コメント({$BlogEntryCommentCount$})</a></BlogEntryIfAllowComments><BlogEntryIfAllowPings>|<a href="{$BlogEntryPermalinkUrl$}#trackbackTitle">トラックバック({$BlogEntryTrackbackCount$})</a></BlogEntryIfAllowPings><BlogEntryIfAllowEntryRatings><span class="rating">|評価平均{$BlogEntryRatingAverageStar$}({$BlogEntryRatingAverage$}) |評価数({$BlogEntryRatingCount$})</span></BlogEntryIfAllowEntryRatings>
</div><!-- entryInfo -->
新しいスクリプト
「忍者おまとめボタン」のjsファイルから、ONETAGButton_Renderという関数部分だけ流用して改変しました。それをsnsBtnMakerというオブジェクトにまとめてあります。
それ以外の部分は独自に書いたコードですが、DOM走査と「続きを読む」の判別で若干長くなっています。
結果的に体感スピードは元のコードと変わらないと思います。ただ、前述の通り、「続きを読む」で出す出さないを変える、ランキングボタンも出す、と言うことで自作コードを採用しています。
いつもはご自由にお使いくださいとしていますが、今回はコードの流用とボタンの画像の著作権問題があるので、私の使っている改変コードを掲載するにとどめます。
このコードの表示結果はこの記事の最後でも見られます。ランキングボタンに関するコードは2ヵ所の青文字部分です。Google リーダーを使う場合は、赤字部分を自分のRSSのURLに変更します。
<script type="text/javascript"> //青字部分がランキング投票ボタン関連 var sns=function(){ var buttons=['twitter','facebook','plusone','mixi','hatena','google_reader','blogmura','blogranking']; var snsBtnMaker={ 'twitter':function(encodedurl,encodedtitle,url,title){ return '<a href="javascript:void(0);" onclick="window.open(\'http://twitter.com/share?original_referer=' +encodeURIComponent(location.href)+'&url='+encodedurl+'&text='+encodedtitle +'&source=tweetbutton\',\'_blank\',\'width=550,height=450\',0);" title="twitterリンク共有する">' +'<img src="http://omt.shinobi.jp/images/twitter_tweet_ninja_m.png" ' +'width="20" height="20" alt="twitterリンク共有する" style="border:none;"></a>'; }, 'facebook':function(encodedurl,encodedtitle,url,title){ return '<a href="http://www.facebook.com/sharer/sharer.php?u='+encodedurl+'&t=' +encodedtitle+'" onclick="window.open(this.href, \'facebook\');return false;" target="_blank" title="facebook">' +'<img src="http://omt.shinobi.jp/images/facebook_share_ninja_m.png" alt="facebook share"></a>'; }, 'plusone':function(encodedurl,encodedtitle,url,title){ return '<a href="https://plusone.google.com/_/+1/confirm?hl=euc-jp&url='+encodedurl +'" onclick="window.open(this.href, \'blank\');return false;" target="_blank" title="Google +1">' +'<img src="http://omt.shinobi.jp/images/google_plusone_ninja_m.png" alt="Google plusone"></a>'; }, 'mixi':function(encodedurl,encodedtitle,url,title){ return '<a href="javascript:void(0)" class="mixi-check-button" data-key="8fcbcc4fddfc34a134ddc0bcac85e85042afc058" ' +'onclick=\'window.open("http://mixi.jp/share.pl?u='+encodedurl+'&k=8fcbcc4fddfc34a134ddc0bcac85e85042afc058", ' +'"share", "width=632,height=456,location=yes,resizable=yes,toolbar=no,menubar=no,scrollbars=no,status=no");\' title="ミクシィ">' +'<img src="http://omt.shinobi.jp/images/mixi_check_ninja_m.png" ' +'style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; ' +'border-left-width: 0px; border-style: initial; border-color: initial; "></a>'; }, 'hatena':function(encodedurl,encodedtitle,url,title){ return '<a href="http://b.hatena.ne.jp/entry/'+url+'" class="hatena-bookmark-button" ' +'data-hatena-bookmark-title="'+title+'" data-hatena-bookmark-layout="simple" ' +'title="このエントリーをはてなブックマークに追加" target="_blank">' +'<img src="http://omt.shinobi.jp/images/hatena_ninja_m.png" alt="" width="20" height="20" style="border: none;" /></a>'; }, 'google_reader':function(encodedurl,encodedtitle,url,title){ //赤字を自分のrssのURLに変更 return '<a href="http://fusion.google.com/add?feedurl='+encodeURIComponent('https://fanblogs.jp/ayzfqir5/index1_0.rdf') +'" target="_blank" title="Google リーダー">' +'<img width="20" height="20" src="http://omt.shinobi.jp/images/google_reader_ninja_icon_m.png" alt="Google reader"></a>'; }, 'blogmura':function(encodedurl,encodedtitle,url,title){ return '<a href="http://it.blogmura.com/html/" target="_blank">' +'<img src="http://it.blogmura.com/html/img/html88_31.gif" width="88" height="31" border="0" ' +'alt="にほんブログ村 IT技術ブログ HTML/CSSへ" /></a>'; }, 'blogranking':function(encodedurl,encodedtitle,url,title){ return '<a href="http://blog.with2.net/link.php?1210233:1072" target="_blank" title="ウェブデザイン ブログランキングへ">' +'<img src="http://image.with2.net/img/banner/c/banner_1/br_c_1072_1.gif" width="110" height="31" border="0" /></a>'; } }; var pagetitle=null; var entries=document.getElementById('entries'); for(var i=0;i<entries.childNodes.length;i++){ var entry=entries.childNodes[i]; if(entry.className=='entry'){ for(var n=0;n<entry.childNodes.length;n++){ var child=entry.childNodes[n]; if(child.className){ if(child.className=='entryContinue'){ break; } if(child.className=='entryInfo'){ for(var j=0;j<child.childNodes.length;j++){ var elem=child.childNodes[j]; if(elem.className=='snsbtn'){ var url=null; var title=null; var encodedurl=null; var encodedtitle=null; var span=elem.getElementsByTagName('SPAN'); for(var num=0;num<span.length;num++){ if(span[num].className=='url_hidden'){ url=span[num].innerHTML; }else if(span[num].className=='title_hidden'){ title=span[num].innerHTML; } } if(!url){ url=location.href; } encodedurl=encodeURIComponent(url); if(title){ encodedtitle=encodeURIComponent(title); }else{ if(!pagetitle){ var t=document.getElementsByTagName('TITLE'); if(!t.length){return;} title=pagetitle=t[0].innerHTML; } encodedtitle=encodeURIComponent(title); } elem.innerHTML=''; for(var len=0;len<buttons.length;len++){ elem.innerHTML+=snsBtnMaker[buttons[len]](encodedurl,encodedtitle,url,title); } elem.style.display='block'; break; } } break; } } } } } } if(window.addEventListener){ window.addEventListener('load',sns,false); }else if(window.attachEvent){ window.attachEvent('onload',sns); } </script>
表示順は配列buttonsの順番どおりです。buttonsの順序を変えれば、表示順は変わります。
ボタンを追加する場合は、buttonsに名前を追加して、それに対応した関数を、オブジェクトsnsBtnMakerに作ります。
スタイルシート
今回のソースに対応したスタイルシートは下記の通りです。
div.entryInfo div.snsbtn{
margin-bottom:8px;
display:none; //スクリプト中でdisplay:block;に変更される
}
div.entryInfo div.snsbtn img{
vertical-align:bottom;
margin:0 2px;
}