阅读器的基本功能:翻页、字体大小设置、切换背景主题色、进度条功能、目录与跳转、添加书签、获取电子书信息、获取当前章节总页码和页数等。
使用命令安装0.3.71版本epubjs:
npm i [email protected]
注:这里之前踩过坑,其他版本进行切换主题时,每一个背景颜色只能切换一次,再次选择其他主题不生效。
解决方法:将版本更换到 0.3.71
添加一个id为read的view标签。
在onLoad生命周期中对电子书进行渲染。
通过new一个Epub对电子书进行初始化解析,生成book。
onLoad() {
this.showEpub();
},
methods:{
showEpub(){
// 对电子书进行初始化解析,路径可以是相对路径或者绝对路径
this.book = new Epub("https://mp-9281e2b4-5558-4603-841a-433fcefa275b.cdn.bspapp.com/cloudstorage/108ca182-d460-4f65-be1b-5819d82d4dfd.epub"
);
}
}
有了电子书的路径后,对电子书进行渲染。
1.book通过renderTo方法对电子书进行渲染,生成rendition对象。
2.renderTo有两个参数:第一个参数是view标签的id,将生成的dom挂在该id的容器上;第二个参数是用来指定电子书的样式和属性,包括宽高,翻页方式等。
3.rendition再通过display方法渲染完成,display支持两种参数:①章节目录中的href链接,可以跳转至指定章节;②cfi值,为epubcfi规范的一个值,不用细究他的构成,能获取到就行。display后面不传参数时默认为0,渲染到首页。
showEpub(){
// 通过new一个Epub对电子书进行初始化解析,生成book,路径可以是相对路径或者绝对路径
this.book = new Epub("https://mp-9281e2b4-5558-4603-841a-433fcefa275b.cdn.bspapp.com/cloudstorage/108ca182-d460-4f65-be1b-5819d82d4dfd.epub");
// book通过renderTo方法对电子书进行渲染,生成rendition对象
this.rendition = this.book.renderTo("read",{
allowScriptedContent: true,
snap: true,
restore: false,
width: "100vw",
height: "100vh",
manager: "continuous",
spread: "none",
flow:
this.flowIndex === 0
? "scrolled-doc"
: this.flowIndex === 1
? "paginated"
: "", //scrolled-doc滚动 paginated分页
})
// 通过display方法进行渲染
this.rendition.display()
}
此处为点击翻页功能,可以为点击屏幕左侧25%,或者点击屏幕右侧25%进行翻上一页和下一页操作。
翻页方法会返回一个promise,进行后续的操作。
// 上一页
prevPage() {
if (this.rendition) {
this.rendition.prev().then(() => {
// 其他逻辑代码
});
}
},
// 下一页
nextPage() {
if (this.rendition) {
this.rendition.next().then(() => {
// 其他逻辑代码
});
}
},
定义一个theme,通过rendition中的Theme对象属性进行字号主题等功能设置。
在这里可以用一个进度条控件,动态设置fontsize大小,并且保存到缓存中,以便下次进入电子书时获取字体大小。字体大小单位为"px"。
this.themes = this.rendition.themes
this.themes.fontSize(this.fontsize + "px")
与字体大小设置一样,切换主题时用的也是theme对象属性。
通过theme.register()为电子书添加主题,通过theme.select(name)选择已经添加好的主题。
// data中定义好主题数组
themeList:[
{
name: "default", // 主题名字
style: { // 主题样式
body: {
color: "#494948", // 文字颜色
background: "#F4F3EF", // 背景颜色
lineColor: "#E4E3DF", // 主题中并无该属性,该属性为自定义目录下划线颜色
},
},
},
{
name: "twoTheme",
style: {
body: {
color: "#39342B",
background: "#D5C6A9",
lineColor: "#C6B89B",
},
},
},
{
name: "threeTheme",
style: {
body: {
color: "#94938F",
background: "#3A3031",
lineColor: "#3F3939",
},
},
},
{
name: "fourTheme",
style: {
body: {
color: "#313635",
background: "#CCE8D1",
lineColor: "#BCD8C1",
},
},
},
{
name: "fiveTheme",
style: {
body: {
color: "rgb(100,110,119)",
background: "#051827",
lineColor: "#0C1E2D",
},
},
},
]
methods:{
// 渲染电子书后调用
registerTheme() {
this.themeList.forEach((item) => {
this.themes.register(item.name, item.style);
});
},
// 触发改变电子书背景主题时调用
setTheme(index) {
this.themes.select(this.themeList[index].name);
},
}
1.进度条功能需要获取locations对象,由于locations对象的生成比较消耗性能,所以默认是不会生成locations对象的。
2.通过epubjs的钩子函数来实现。借助book解析完成之后回调的ready方法来生成。
3.通过book的locations.cfiFromPercentage()方法获取当前百分比所对应的epubcfi,通过this.rendition.display(epubcfi)渲染即可跳到相应位置。
注:在进度条可操作之前,必须是分页执行完之后得到location对象才可对进度条进行操作。(可添加一标识,判断locations对象是否得到,未得到时提示进度条加载中,完成后显示在操作)。
showEpub(){
// 通过new一个Epub对电子书进行初始化解析,生成book,路径可以是相对路径或者绝对路径
this.book = new Epub("https://mp-9281e2b4-5558-4603-841a-433fcefa275b.cdn.bspapp.com/cloudstorage/108ca182-d460-4f65-be1b-5819d82d4dfd.epub");
// book通过renderTo方法对电子书进行渲染,生成rendition对象
this.rendition = this.book.renderTo("read",{
allowScriptedContent: true,
snap: true,
restore: false,
width: "100vw",
height: "100vh",
manager: "continuous",
spread: "none",
flow:
this.flowIndex === 0
? "scrolled-doc"
: this.flowIndex === 1
? "paginated"
: "", //scrolled-doc滚动 paginated分页
})
// 通过display方法进行渲染
this.rendition.display()
this.book.ready
.then(() => {
return this.book.locations.generate();
})
.then((result) => {
// result为book生成电子书的cfi的一个数组。与下面this.locations中的_locations属性一致
this.locations = this.book.locations;
console.log("locations", this.locations);
// bookAvailable标识,默认为false,为true时代表进度条可操作
this.bookAvailable = true;
})
}
调整进度条跳转至对应页面。
onProgressChange(e) {
// e为进度条保留两位小数点的数字
const percentage = e / 100;
// location为根据进度生成的cfi值
const location =
percentage > 0 ? this.locations.cfiFromPercentage(percentage) : 0;
console.log("location", location);
this.rendition.display(location);
},
1.通过book的navigation对象,可以获取到电子书的目录。
2.通过epubjs的钩子函数来实现。借助book解析完成之后回调的ready方法来生成。
3.由于目录为一个tree类型,所以页面上需用tree组件来渲染。
this.book.ready
.then(() => {
this.navigation = this.book.navigation;
// toc为总目录,目录可分级
this.toc = this.book.navigation.toc;
return this.book.locations.generate();
})
.then((result) => {
// result为book生成电子书的cfi的一个数组。与下面this.locations中的_locations属性一致
this.locations = this.book.locations;
console.log("locations", this.locations);
// bookAvailable标识,默认为false,为true时代表进度条可操作
this.bookAvailable = true;
})
Navigation.toc表示电子书的目录结构,是一个数组,toc下的每一个元素对应一个目录,toc[n].href表示目录路径(链接),toc[n].label是当前目录的名字,toc[n].subitems里面包含的是该目录下还有其他的二级(三级)目录,可根据需要使用几级目录。
获取到目录后,可以通过点击树组件中的章节获取到该章节对应的数据(toc数组中某一项),再根据该项中的href属性进行跳转。
jumpTo(item){
this.rendition.display(item.href)
}
添加书签功能需要使用到rendition对象中的currentLocation方法。
currentLocation.start.cfi为当前页的cfi值,可根据该cfi值进行跳转。
// 获取当前页cfi值并保存到数组中
handleMark() {
const currentLocation = this.book.rendition.currentLocation();
this.bookmarks.push(currentLocation.start.cfi);
},
// 点击,根据cfi值跳转
toMark(cfi) {
this.rendition.display(cfi)
},
通过book中的package对象获取电子书信息:
1.manifest用来获取电子书的所有用到的文件信息;
2.metadata用来获取电子书的出版信息,其中titile为电子书的名字;
3.ncxPath为目录的路径;
4.spine为阅读顺序。
this.book.loaded.metadata.then((meta) => {
console.log("meta", meta);
this.meta= meta;
});
获取当前章节页码和总页数与添加书签功能一样需要用到rendition对象中的currentLocation方法。
total:当前章节总页数;
page:当前页在当前章节页码。
showPage(page) {
const currentLocation = this.book.rendition.currentLocation();
console.log("当前位置", {
...currentLocation.start.displayed,
});
this.bookInfo.pageInfo = {
total: page?.total || currentLocation.start.displayed.total,
page: page?.page || currentLocation.start.displayed.page,
};
},
以上就完成了基于epubjs开发的基本的阅读器功能,样式和点击事件部分可以由各位根据需求来添加,如有问题和错误之处欢迎指出~