目次を表示する
次に、EPUBに含まれるXHTMLファイルの名前をEPUBビューアーの目次として表示します。ファイル名がクリックされたら内容を表示する処理も追加します。
XHTMLファイルの一覧はすでに関数analysisXMLで取得できていて、以下のように変数xhtmlListに入っています。
var xhtmlList = analysisXML(zip.files["OEBPS/content.opf"].data);
xhtmlListは配列変数で要素ごとにXHTMLファイル名が格納されているので、for()を使って配列要素の数だけ繰り返すと目次を作成できます。目次の文字をクリックするとXHTMLファイル内容を表示するview関数を呼び出すようにします。view関数の引数にXHTMLファイル名(ファイルパス)を渡します。
var contentsList = "<ol>"; for(i=0; i<xhtmlList.length; i++){ contentsList += '<li><a href="#" onclick=view("'+xhtmlList[i]+'")>'+xhtmlList[i]+"</a></li>"; }
view関数では渡されたXHTMLファイル名を元にページ上に内容を表示します。特に難しい処理はないので、これまでの説明で理解できるでしょう。
function view(url){ var text = zip.files["OEBPS/"+url].data; //指定されたページを表示 document.getElementById("bookContents").innerHTML = Utf8.decode(text); }
ここまでをまとめたのがサンプル4です。EPUBファイルを選択してEPUB表示ボタンをクリックすると、左側に目次が表示されます。目次欄に表示されたXHTMLファイル名(リンク)をクリックすると右側に内容が表示されます。
■サンプル4
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>JavaScript EPUB Viewer</title> <link rel="stylesheet" href="css/main.css" type="text/css" media="all" /> <script type="text/javascript" src="js/sjis.js" charset="shift_jis"></script> <script type="text/javascript" src="js/zip.js" charset="shift_jis"></script> <script type="text/javascript" src="js/utf8.js" charset="utf-8"></script> <script> var zip = null; window.addEventListener("load", function(){ document.getElementById("viewEPUB").addEventListener("click", function(){ document.getElementById("bookIndex").innerHTML = ""; document.getElementById("bookContents").innerHTML = ""; var fileData = document.getElementById("myFile").files[0]; var reader = new FileReader(); reader.onload = function(evt){ var bytes = []; var byteData = evt.target.result; for (var i=0; i<byteData.length; i++)bytes[i] = byteData.charCodeAt(i); zip = Zip.inflate(bytes); // console.dir(zip.files["OEBPS/content.opf"]); var xhtmlList = analysisXML(zip.files["OEBPS/content.opf"].data); // XMLデータ解析 // 目次を生成 var contentsList = "<ol>"; for(i=0; i<xhtmlList.length; i++){ contentsList += '<li><a href="#" onclick=view("'+xhtmlList[i]+'")>'+xhtmlList[i]+"</a></li>"; } document.getElementById("bookIndex").innerHTML = contentsList+"</ol>"; } reader.readAsBinaryString(fileData); }, true); }, true); // XMLデータを解析してXHTMLファイル一覧を返す function analysisXML(xmldata){ document.getElementById("epubxml").innerHTML = xmldata; var d = document.getElementById("epubxml"); var fileList = []; // EPUB表示に必要なファイル項目を取得 var itemTag = d.getElementsByTagName("manifest")[0].getElementsByTagName("item"); // 表示順を示すitemrefタグを取得 var indexItem = d.getElementsByTagName("spine")[0].getElementsByTagName("itemref"); // ページの表示順番を取得(IDからファイル名を取得) for(var i=0; i<indexItem.length; i++){ var ID = indexItem[i].getAttribute("idref"); // IDを読み出す for(var j=0; j<itemTag.length; j++){ var cID = itemTag[j].getAttribute("id"); // IDを読み出す // console.log(ID+" = "+cID); // 確認したい人はコメント削除してください if (ID == cID){ fileList.push(itemTag[j].getAttribute("href")); // href属性を読み出す console.log(itemTag[j].getAttribute("href")); // 確認したい人はコメント削除してください break; // ループから抜ける } } } return fileList; } // 目次がクリックされたら対応するページを表示 function view(url){ var text = zip.files["OEBPS/"+url].data; //指定されたページを表示 document.getElementById("bookContents").innerHTML = Utf8.decode(text); } </script> </head> <body> <h1>JavaScript EPUB Viewer</h1> <form action="./test.cgi" method="get"> <input type="file" id="myFile" /> <input type="button" id="viewEPUB" value="EPUB表示" /> </form> <div id="bookIndex">- 目次 -<br></div> <div id="bookContents">本文</div> <div id="epubxml"></div> </body> </html>