2010年11月1日 星期一

[Javascript] 模仿 Monocle 分頁效果之簡單的 HTML 閱讀器

Monocle 是一套 Javascript 電子書閱讀器,以 EPUB 格式結構作為設計,使用方式不是餵給他一個 EPUB 檔案,而是依照 Monocle 所定義的資料進行實做,例如某個 function 要回傳書目,這類似於 EPUB 裡的 OPF content file 或 Spine file 等,另外還要實做一個回傳指定章節的內容,如問你第一章時,要回傳第一章整個 XHTML 內容等,以此做出豐富的閱讀效果。


關於翻頁效果,可以參考這篇 [Javascript] EPUB Reader 翻頁效果的原理,在此就仿照 Monocle 的分頁效果,使用 jQueryCSS Multi-column Layout Module (W3C Candidate Recommendation 17 December 2009) 實作簡單的 HTML 閱讀器,順便筆記一下。


程式碼 - index.html:


<!DOCTYPE html>
<html xml:lang="utf-8" lang="utf-8" xmlns="http://www.w3.org/1999/xhtml">
        <head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
                <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
                <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
                <LINK REL="StyleSheet" HREF="style.css" TYPE="text/css"/>
                <script type="text/javascript">
                        try{
                                console.log( '' );
                        }catch(err){
                                console = {}
                                console.log = function(){}
                        }
                        var page = 1;
                        $( document ).ready( function() {
                                $( '#info' ).hide();
                                $( '#tools' ).hide();
                                $( '#touch_menu' ).click( function(){
                                        var obj;
                                        obj = $( '#info' );
                                        if( obj.is( ':visible' ) )
                                                obj.hide();
                                        else
                                                obj.show();

                                        obj = $( '#tools' );
                                        if( obj.is( ':visible' ) )
                                                obj.hide();
                                        else
                                                obj.show();
                                } );
                                var window_width = $(window).width();
                                $( '#show' ).width( window_width);
                                $( '#content' ).css( '-moz-column-width' , window_width );
                                $( '#content' ).css( '-webkit-column-width' , window_width );
                                $( '#touch_next' ).click( function(){
                                        var obj = document.getElementById( 'show' );
                                        var tmp = obj.scrollLeft;
                                        obj.scrollLeft += $( '#show' ).width();
                                        if( tmp == obj.scrollLeft )
                                                getPage( ++page );
                                } );
                                $( '#touch_prev' ).click( function(){
                                        var obj = document.getElementById( 'show' );
                                        if( obj.scrollLeft > 0 )
                                        {
                                                obj.scrollLeft -= $( '#show' ).width();
                                        }
                                        else if( page > 1 )
                                                getPage( --page , true );
                                        else
                                                obj.scrollLeft = 0;
                                } );
                                getPage( page );
                        } );


                        function getPage( page , be_last )
                        {
                                $.ajax({
                                        //
                                        // url 為 EPUB 檔案解壓縮後,章節檔案的位置
                                        // 此例剛好章節檔名是 chapter1.html ~ chapter100.html
                                        // 因此翻頁就只是類似從 chapter1.html 換到 chapter2.html 而已
                                        //
                                        url:'epub/OPS/chapter'+page+'.html', 
                                        type:'GET',
                                        async: false,
                                        success:function(data){
                                                $( '#content' ).empty();
                                                xmlDoc = new DOMParser().parseFromString( data , "text/xml" );
                                                while( xmlDoc.hasChildNodes() )
                                                {
                                                        var node = xmlDoc.removeChild(xmlDoc.firstChild);
                                                        console.log( node.nodeType );
                                                        if (node.nodeType == 1)
                                                        {
                                                                $( '#content' ).append( node );
                                                        }
                                                        else if (node.nodeType == 3 && !node.nodeValue.match(/^\s+$/))
                                                        {
                                                                var elem = document.createElement('div');
                                                                elem.appendChild(node);
                                                                $( '#content' ).append( elem );
                                                        }
                                                }
                                        }
                                });
                                var obj = document.getElementById( 'show' );
                                if( !obj )
                                        return;
                                if( be_last == undefined )
                                {
                                        obj.scrollLeft = 0;
                                }
                                else
                                {
                                        obj.scrollLeft += 999999;
                                }
                        }
                </script>
        </head>
        <body>
                <div id="container"><div id="show"><div id="content"></div></div></div>
                <div id="info"></div>
                <div id="tools"></div>
                <div id="touch_menu"></div>
                <div id="touch_next"></div>
                <div id="touch_prev"></div>
        </body>
</html>


程式碼 - style.css:


html, body {
        margin: 0;
}
#container , #show , #content , #info , #tools , #touch_menu , #touch_prev , #touch_next {
        position:absolute;
        width:100%;
        height:100%;
}
#container {
        background-color:rgba(75%, 75%,75%,0.5);
        z-index: 0;
}
#touch_menu , #touch_prev , #touch_next {
        z-index: 10;
}
#touch_menu {
        background-color:rgba(70%,70%,70%,0.5);
        width:40%;
        top:0;
        left:30%;
}
#touch_prev , #touch_next {
        width:30%;
}
#touch_prev {
        top:0;
        left:0;
        background-color:rgba(90%,90%,90%,0.4);
}
#touch_next {
        top:0;
        left:70%;
        background-color:rgba(90%,90%,90%,0.4);
}

#info , #tools {
        height:10%;
        z-index: 100;
}
#info {
        top:0px;
        background-color:rgba(0%,10%,20%,0.5);
}
#tools {
        top:90%;
        background-color:rgba(0%,10%,20%,0.5);
}
#show {
        z-index:100;
        width:1000px;
        overflow: hidden;
}
#content {
        font-size:20px;
        -moz-column-gap: 0pt; -moz-column-width: 1000px;
        -webkit-column-gap: 0pt; -webkit-column-width: 1000px;
        z-index:100;
}


使用上需要更新 ajax 那一塊,把 url 的規則修改,不然就自己擺個幾個網頁,如 chapter1.html, chapter2.html 就可以試試效果囉。


成果:


ereader
分成三塊,中間點了顯示上下兩個圖層外,可以拿來規劃成其他服務,另外,左右兩邊就只是翻頁而已。


上述程式碼大概只有 ajax 裡的 sucess function 裡的部分動作,是從 Monocle 參考修改而來的,除此之外都非常簡單,只是翻頁計算的事情。此次僅為了熟習 CSS Multi-column Layout Module 翻頁,大家要多支持 Monocle 這套閱讀器,他可還是 MIT License 的 open source!另外,還可以看到 Monocle 網站的最新消息,推出了 BOOKish 網站服務,感覺未來走向跟 ibis reader 差不多吧。


沒有留言:

張貼留言