2007/03/05

Blogger Widgetで「続きを読む」を自動化。-- 3.3

そろそろ完結にしたい Bloggerでの「続きを読む」機能ですが、簡単に思っていたことが意外と深みに嵌っているような、単なる手抜きの積み重ねのような複雑な様相を呈してきました・・・。

全てはBloggerがBetaからNewになっても、実装というか方針が中途半端なんじゃないかと思ってたりもしますが、個人的には「制約は人を育てる」なんて志向があるんで、これもOKと受け止めております。

そんな感じですが前回の記事の続きとして、早々に余計なReadmoreをタグごと隠すスクリプト(Javascript)を書いてみました。帰宅途中に運転しながら考えて、着替える前に コードを書く⇒テスト の流れの15分ですから例によって寄せ集めですが、それなりに知識なのかスキルなのかが蓄積されてきたらしく、この素早さはちょっと快適。


今回のコードはテンプレートへのタグ追加とセットで動く感じでになりますが、テンプレートへの加工であり記事本体には手を入れていないので、前回まで手順を行っていてもテンプレートを書き換えてスクリプトを追加しただけで表示が変わります。

つまり元々のテンプレートさえBackupしておけば、直ぐに元に戻せますから安心して試せます。

まずはテンプレートの改変。基本的には前々回の記事と同様ですが、後で隠す必要があるので判別の為、<p>タグにクラス名を付加しました。


<div class='post-body'>
  <p>
    <data:post.body/>
  </p>
  <b:if cond='data:blog.pageType != "item"'>
    <p class='readmore2'>
      <a expr:href='data:post.url'>
        続きを読む・・
      </a>
    </p>
  </b:if>
</div>
<div class='post-footer'>


クラス名があるといっても表示・非表示の条件が位置ではなく、「兄弟にfullpostクラスのタグがあるか? 」なんて条件になりますのでスタイルシート指定では対応出来ないのです。(私の知識範囲では)

そこで実行時にスクリプトで該当するclass="readmore2"のタグに対してstyle="display:none"で隠す事にします。該当する条件は本文中にclass="fullpost"なタグが含まれてない事になります。

Javascriptなソースはこんな感じです。


// Remove unnecessarilly ReadMore elements.

// Add Event Listtener
{
    // for Mozilla and Opera9
    if(document.addEventListener){ 
        document.addEventListener("DOMContentLoaded", removeExtraReadMore, false);
    }        

    // for Internet Explorer (using conditional comments)        
    /*@cc_on @*/
    /*@if (@_win32)
        document.write('<script id="_decoy_removeExtraReadMore" defer src="javascript:void 0"><\/script>');
        document.getElementById("_decoy_removeExtraReadMore").onreadystatechange = function(){
            if(this.readyState=='complete'){
                removeExtraReadMore();
            }
        };
    /*@end @*/

}


// removeExtraReadMore
function removeExtraReadMore(){
    // Get all "div" elements which class name are "post-body"
    var elms=getElementsByClassName(document.body,"div","post-body");
    
    for(var i=0,elm=elms[0];elms.length>0 &&i<=elms.length;elm=elms[i++]){
        var eFullPosts = getElementsByClassName(elm,"*","fullpost");
        
        if(eFullPosts.length >0)continue// has some fullpost tag.
        
        var eReadMores = getElementsByClassName(elm,"*","readmore2");
        
        // Remove Readmore tags.
        for(var l=0,eRm=eReadMores[0];eReadMores.length>0 &&l<=eReadMores.length;eRm=eReadMores[l++])
            if (document.documentElement.getAttribute("style") == document.documentElement.style)
                eRm.style.display="none";
            else
                eRm.setAttribute("style","display:none;");
                
    }// __for(elms) 

}

//
function getElementsByClassName(elm, tagName, className){
    var arRslt = new Array();
    var elms = (tagName == "*" && elm.all)
                    ? elm.all : elm.getElementsByTagName(tagName);

    className = className.replace(/\-/g, "\\-");
    var re = new RegExp("(^|\\s)" + className + "(\\s|$)");

    for(var i=0; i<elms.length; i++){
        var e = elms[i];      
        if(re.test(e.className)){
            arRslt.push(e);
        }   
    }
    return arRslt
}

//
function getElementsByClassName(elm, tagName, className){
    var arRslt = new Array();
    var elms = (tagName == "*" && elm.all)
                    ? elm.all : elm.getElementsByTagName(tagName);

    className = className.replace(/\-/g, "\\-");
    var re = new RegExp("(^|\\s)" + className + "(\\s|$)");

    for(var i=0; i<elms.length; i++){
        var e = elms[i];      
        if(re.test(e.className)){
            arRslt.push(e);
        }   
    }
    return arRslt
}


Sctiptタグが何処に埋められても問題がないように、全てのコンテントが読み込まれてから処理するようになっています。実際にはDOMContentLoadedを使っていて、Onloadで処理する場合は画像等の読み込み後のイベントになるので、それよりも早く処理が開始されてちょっと快適なハズです。

まぁこんなのまでテンプレートに書き込むのは大変なので私は外部ファイルにして、テンプレートの最後の方に書き加えています。


    </div>
    <!-- end outer-wrapper -->
    <script src='http://isawseashells.googlepages.com/RemoveExtraReadMore.js' type='text/javascript'/>
    
  </body>
</html>


これで要約設定をしていない記事に対して余計な「続きを読む」が出ることは無くなります。

多分これで「続きを読む」シリーズは完結じゃないかと思うですが、どうでしょうか???

関連のありそうな記事

0 コメント: