小組項目 “基於JavaScript的讀書平臺” 正在開發中,預計年底上線。 由於之前有Flask框架的web開發經驗,產品的第一個版本我負責了web平臺搭建,技術選型: 伺服器端:nodejs-express 前端:React、Ant Design 資料庫:Mysql 之前Flask框架下的前端技 ...
小組項目 “基於JavaScript的讀書平臺” 正在開發中,預計年底上線。
由於之前有Flask框架的web開發經驗,產品的第一個版本我負責了web平臺搭建,技術選型:
伺服器端:nodejs-express
前端:React、Ant Design
資料庫:Mysql
之前Flask框架下的前端技術使用的是基礎的HTML+CSS,和一小部分JQuery效果,因為一直對前端比較感興趣,這次大膽的用上學的不那麼扎實(或者說更流行)的React,實踐指導理論。
“讀書平臺”打造的是一個:能夠線上讀書、即時分享、方便批註筆記的高度定製化、個性化書庫。
回到題目上,epub是最流行的電子書規範之一,網路上對於Java Web有不少合適的方法來解析和呈現epub文件,但在JavaScript特別是瀏覽器端渲染的中間件則只有epub.js一家。
網路上關於epub.js的介紹比較少(儘管github上已經2K星了),更多的是概念性的內容,如:
epub.js是支持跨多個設備的,在瀏覽器端渲染EPUB文件的JavaScript庫,提供通用的電子書功能界面(如渲染、持久和分頁)不需要開發專用的應用程式或插件。
具體用法因人而異,在此我介紹結合React使用的案例:
如圖是使用React和AntD構建的後臺管理系統,對於文件的上傳下載刪除功能已經做好,epub.js解決的是對於epub規格的文件如何解析和呈現。
點擊“閱讀本書”操作:
這就是epub.js結合React提供的基礎單頁閱覽頁面了,epub.js中間件封裝瞭解析epub文件的過程。左右兩側的翻頁鍵都可以按需定製,甚至用AntD的組件來替代也不是問題。
簡單用法在官方文檔寫的很容易理解:https://github.com/futurepress/epub.js
有多種解析模式可以選擇,單頁閱覽是預設模式。
但對於一個專業的讀書平臺來說,簡單呈現圖書內容是遠遠不夠的,epub.js提供了更多的介面:
https://github.com/futurepress/epub.js/blob/master/documentation/README.md
方法:
ePub(bookPath, options)
創建EPUB圖書實例:
bookPath可選參數,指定epub文件路徑,可以是網路資源,也可以是本地資源。
var Book = ePub("url/to/book/"); // With default options var Book = ePub({ restore: true }); Book.open("url/to/book/"); // Books can be opened later
Options可選參數,配置解析參數
{ bookPath : null, version: 1, // Changing will cause stored Book information to be reloaded restore: false, // Skips parsing epub contents, loading from localstorage instead storage: false, // true (auto) or false (none) | override: 'ram', 'websqldatabase', 'indexeddb', 'filesystem' spreads: true, // Displays two columns fixedLayout : false, //-- Will turn off pagination styles : {}, // Styles to be applied to epub width : false, //width和height可以設置圖書內容的寬和高,預設值是不設置,此時會填滿父視窗。 height: false, }
解析圖書的更多方法:
Book.open(bookPath) 打開指定路徑的圖書,和構造函數的作用類似,只是將配置和解析的過程分開
var Book = ePub({ restore: true }); Book.open("url/to/book/"); // Books can be opened later
也可以帶擴展名:
Book.open("url/to/book.epub");
Book.renderTo(element) 將解析好的圖書追加到某個HTML結點並渲染,此時epub圖書內容在HTML中呈現。(使用的是iframe標簽)
var Book = ePub("url/to/book/", { restore: true }); var $el = document.getElementById("div-id"); Book.renderTo($el);
參數也可以是字元串表示:
var Book = ePub("url/to/book/"); Book.renderTo("div-id");
Book.nextPage()
Book.prevPage()
在閱讀頁面中的翻頁控制函數,添加到按鈕事件函數:
<div onclick="Book.prevPage();">‹</div> <div onclick="Book.nextPage();">›</div>
必須在渲染之後,才會響應翻頁。
Book.displayChapter(chap, end) 顯示指定章節:
載入指定的章節到頁面上,載入的是這一章的第一頁:
Book.displayChapter('/6/4[chap01ref]!/4[body01]/10');
第二個參數設置為true,將載入這一章的最後一頁:
Book.displayChapter(3, true);
Book.goto(url)跳轉到指定章節:
載入指定的章節(需要有pageMap)
var skip = Book.goto("chapter_001.xhtml"); skip.then(function(){ console.log("On Chapter 1"); })
通常用來顯示一些帶有指定章節鏈接的表格
Book.setStyle(style, val, prefixed)設置圖書內容的樣式:
Book.setStyle("font-size", "1.2em");
Book.removeStyle(style)移除設置的樣式。
Book.destroy()刪除iframe和事件函數。
Promises
Book.getMetadata()在回調函數中獲取meta數據:
Book.getMetadata().then(function(meta){ document.title = meta.bookTitle+" – "+meta.creator; });
返回一個對象:
{ "bookTitle": "The title of the book", "creator": "Book Author", "description": "The description/synopsis of the book", "pubdate": "", "publisher": "The Publisher", "identifier": "The ISBN", "language": "en-US", "rights": "Copyright text", "modified_date": "", "layout": "", "orientation": "", "spread": "", "direction": null }
Book.getToc()在回調函數中獲取toc,是一個包含目錄結構的數組對象。
Book.getToc().then(function(toc){
console.log(toc);
});
Book.generatePagination()進行分頁,可選參數為頁面大小:
book.generatePagination().then(function(toc){ console.log("Pagination generated"); }); book.generatePagination(pageWidth, pageHeight).then(function(toc){ console.log("Pagination generated"); });
可響應的事件:
book:ready
book:stored
book:online
book:offline
book:linkClicked
book.on('book:linkClicked', function(href) { console.log(href); });
book:pageChanged
{ anchorPage: 2 percentage: 0.5 pageRange: [1, 2, 3] }
pageChanged事件響應當前頁數,前提是必須有一個頁碼表
book.on('book:pageChanged', function(location){ console.log(location.anchorPage, location.pageRange) });
renderer:resized
renderer:chapterDisplayed
renderer:chapterUnloaded
renderer:locationChanged
"epubcfi(...)"
locationChanged事件響應當前位置信息,可以用來做進度條等效果。
book.on('renderer:locationChanged', function(locationCfi){
console.log(locationCfi)
});
renderer:visibleRangeChanged