欢迎使用
效果展示:https://zuowb.cn/(欢迎收藏使用)
所用技术
vue2.0,epub.js,IndexDB,webpack14.0
epub.js介绍
gittub地址:https://github.com/futurepress/epub.js
官方文档:http://epubjs.org/documentation/0.3/
获取epub.js
npm install epub.js
在项目中导入对应库
import ePub from 'epubjs'
基础 方法:
//首先获取book对象
//使用文件地址导入
var book = ePub('/book/xxx.epub')
//或者使用ArrayBuffer导入
//var book = ePub(arrayBuffer)
//绑定到页面上对应id的元素上如<div id='readHere'> </div>
var rendition = book.renderTo('readHere',{
width:'100%', //也可以是'980px'这样的
height:'100%',
flow:'paginated' //默认是'paginated',是分页模式,'scrolled-doc'是滚动式
})//其它参数具体可以参考官方文档
//渲染到页面上
rendition.display() //显示第一页 //现在可以看到页面上显示书籍了
//实现翻页
rendition.prev() //下一页
rendition.next() //上一页 //现在可以一口气将一本书从头看到尾了
//获取目录对象
book.ready.then(()=>{
var catalog = that.navigation.toc //获得一个对象数组,包含每一章节题目和跳转地址。
return book.locations.generate() //返回一个全书的解析,包括cfi与percentage的详细对应信息
}).then(()=>{
var location = book.locations //获得全书的解析,如果书籍解析慢,问题就在这,比较费时
var bookAvailable = true //到此,书籍的准备才算完成
})
//保存阅读位置
if (bookAvailable){
var cfi = rendition.currentLocation().start.cfi //cfi记录当前页面起始位置
var percentage = location.percentageFromCfi(cfi) //percentage记录当前页面在全书的位置,cfi与percentage一一对应
//配合rendition.display()可以在书籍渲染时显示指定的位置,
rendition.display(cfi) //or
rendition.display(percentage)
//获取cfi必须在已经生成了location对象,即已经完成了对全书的解析。
//一般的epub书籍大小为3M以内,解析时间大概为几秒,但如果是20M的网络小说类解析全本则需要几分钟。。。所幸是异步,你解析你的,不妨碍我看书,嘻嘻
}
整体的流程如下:
async initBook(){
let that = this
that.book = ePub('./xxx.epub')
that.rendition = that.book.renderTo('readHere',{
flow:'paginated',
width:'100%',
height:'100%'})
that.rendition.display()
that.themes.register({"night":{body:{"background-color":"#0f1112","color":"#666"}},"day":{body:{"background-color":"rgb(246, 241, 231)","color":"#262626"}}}) //注册几个主题,使用this.themes.update('night')切换主题
that.themes.fontSize('16px') //设置字体大小
await that.book.loaded.metadata.then(()=>{
var title = metadata.title //获取到书籍名称
})
await that.book.loaded.cover.then( async function(cover){
await that.book.archive.createUrl(cover).then(url=>{
var bookCover = url}) //获取到书籍封面
})
await that.book.ready.then(()=>{
var catalog = that.book.navigation.toc
for (let item of catalog){
that.catalogs.push({title:item.label,href:item.href}) //获得目录数组
}
return that.book.locations.generate()
}).then(()=>{
that.location = that.book.locations //获得location对象
that.bookAvailable = true
that.cfi = that.rendition.currentLocation().start.cfi
})
}
async prePage(){
if(this.rendition){
await this.rendition.prev().then(()=>{
this.percentage = this.location.percentageFromCfi(this.rendition.currentLocation().start.cfi) //每次翻页更新阅读进度,方便显示也方便书签保存
})
}
async nextPage(){
if(this.rendition){
await this.rendition.next().then(()=>{
this.percentage = this.location.percentageFromCfi(this.rendition.currentLocation().start.cfi) //每次翻页更新阅读进度,方便显示也方便书签保存
})
}
}
避坑
- 异步
在使用epub.js时,有很多方法都是异步进行的,得等它执行完毕后才能得到结果。比如rendition.prev()不用async-await的话获得的cfi总是有问题。再比如要等到location对象解析完毕,才会有percentage,和cfi相关的方法,但是在书籍大的时候不够及时。所以我保存进度的时候会将当前percentage保存起来,这样下次打开网站可以接着上次的继续阅读,让浏览器在后台解析,不影响阅读。但此时是无法保存书签的(同理)暂时没有更好的办法。。。 - webpack打包
本地项目完成后我想打包到网站上,结果因为是第一次用webpack,硬是整了三天才完成。。。出现问题太多了,这里就不说了(说也说不清。。。),很多都是版本号问题。。。
最后
最后放上我的源码,文字说不清的东西,就看代码吧。
github仓库