前言
阅读器的基本功能:翻页、字体大小设置、切换背景主题色、进度条功能、目录与跳转、添加书签、获取电子书信息、获取当前章节总页码和页数等。
功能的实现
1.引入epubjs
使用命令安装0.3.71版本 epubjs :
npm i epubjs@0.3.71
注:这里之前踩过坑,其他版本进行切换主题时,每一个背景颜色只能切换一次,再次选择其他主题不生效。
解决方法:将版本更换到 0.3.71
2.为电子书准备容器
添加一个 id 为 read 的 view 标签。
<view />
3.渲染电子书
在 onLoad 生命周期中对电子书进行渲染。
通过 new 一个 Epub 对电子书进行初始化解析,生成 book 。
onLoad() {
();
},
methods:{
showEpub(){
// 对电子书进行初始化解析,路径可以是相对路径或者绝对路径
= new Epub("/cloudstorage/"
);
}
}
有了电子书的路径后,对电子书进行渲染。
- book 通过 renderTo 方法对电子书进行渲染,生成 rendition 对象。
- renderTo 有两个参数:第一个参数是 view 标签的 id ,将生成的 dom 挂在该 id 的容器上;第二个参数是用来指定电子书的样式和属性,包括宽高,翻页方式等。
- rendition 再通过 display 方法渲染完成, display 支持两种参数:①章节目录中的 href 链接,可以跳转至指定章节;② cfi 值,为 epubcfi 规范的一个值,不用细究他的构成,能获取到就行。 display 后面不传参数时默认为 0 ,渲染到首页。
showEpub(){
// 通过new一个Epub对电子书进行初始化解析,生成book,路径可以是相对路径或者绝对路径
= new Epub("/cloudstorage/");
// book通过renderTo方法对电子书进行渲染,生成rendition对象
= ("read",{
allowScriptedContent: true,
snap: true,
restore: false,
width: "100vw",
height: "100vh",
manager: "continuous",
spread: "none",
flow:
=== 0
? "scrolled-doc"
: === 1
? "paginated"
: "", //scrolled-doc滚动 paginated分页
})
// 通过display方法进行渲染
()
}
4.翻页功能
此处为点击翻页功能,可以为点击屏幕左侧 25% ,或者点击屏幕右侧 25% 进行翻上一页和下一页操作。
翻页方法是异步的,会返回一个 promise ,进行后续的操作。
// 上一页
prevPage() {
if () {
().then(() => {
// 其他逻辑代码
});
}
},
// 下一页
nextPage() {
if () {
().then(() => {
// 其他逻辑代码
});
}
},
5.字体大小设置
定义一个 theme ,通过 rendition 中的 Theme 对象属性进行字号主题等功能设置。
在这里可以用一个进度条控件,动态设置 fontsize 大小,并且保存到缓存中,以便下次进入电子书时获取字体大小。字体大小单位为 "px" 。
=
( + "px")
6.切换背景主题色
与字体大小设置一样,切换主题时用的也是 theme 对象属性。
通过 () 为电子书添加主题,通过 (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() {
((item) => {
(, );
});
},
// 触发改变电子书背景主题时调用
setTheme(index) {
([index].name);
},
}
7.进度条功能
- 进度条功能需要获取 locations 对象,由于 locations 对象的生成比较消耗性能,所以默认是不会生成 locations 对象的。
- 通过 epubjs 的钩子函数来实现。借助 book 解析完成之后回调的 ready 方法来生成。
- 通过 book 的 () 方法获取当前百分比所对应的 epubcfi ,通过 (epubcfi) 渲染即可跳到相应位置。
注:在进度条可操作之前,必须是分页执行完之后得到 location 对象才可对进度条进行操作。(可添加一标识,判断 locations 对象是否得到,未得到时提示进度条加载中,完成后显示在操作)。
showEpub(){
// 通过new一个Epub对电子书进行初始化解析,生成book,路径可以是相对路径或者绝对路径
= new Epub("/cloudstorage/");
// book通过renderTo方法对电子书进行渲染,生成rendition对象
= ("read",{
allowScriptedContent: true,
snap: true,
restore: false,
width: "100vw",
height: "100vh",
manager: "continuous",
spread: "none",
flow:
=== 0
? "scrolled-doc"
: === 1
? "paginated"
: "", //scrolled-doc滚动 paginated分页
})
// 通过display方法进行渲染
()
.then(() => {
return ();
})
.then((result) => {
// result为book生成电子书的cfi的一个数组。与下面中的_locations属性一致
= ;
("locations", );
// bookAvailable标识,默认为false,为true时代表进度条可操作
= true;
})
}
调整进度条跳转至对应页面。
onProgressChange(e) {
// e为进度条保留两位小数点的数字
const percentage = e / 100;
// location为根据进度生成的cfi值
const location =
percentage > 0 ? (percentage) : 0;
("location", location);
(location);
},
8.目录与跳转
- 通过 book 的 navigation 对象,可以获取到电子书的目录。
- 通过 epubjs 的钩子函数来实现。借助 book 解析完成之后回调的 ready 方法来生成。
- 由于目录为一个 tree 类型,所以页面上需用 tree 组件来渲染。
.then(() => {
= ;
// toc为总目录,目录可分级
= ;
return ();
})
.then((result) => {
// result为book生成电子书的cfi的一个数组。与下面中的_locations属性一致
= ;
("locations", );
// bookAvailable标识,默认为false,为true时代表进度条可操作
= true;
})
表示电子书的目录结构,是一个数组, toc 下的每一个元素对应一个目录, toc[n].href 表示目录路径(链接), toc[n].label 是当前目录的名字, toc[n].subitems 里面包含的是该目录下还有其他的二级(三级)目录,可根据需要使用几级目录。
获取到目录后,可以通过点击树组件中的章节获取到该章节对应的数据( toc 数组中某一项),再根据该项中的 href 属性进行跳转。
jumpTo(item){
()
}
9.添加书签
添加书签功能需要使用到 rendition 对象中的 currentLocation 方法。
为当前页的 cfi 值,可根据该 cfi 值进行跳转。
// 获取当前页cfi值并保存到数组中
handleMark() {
const currentLocation = ();
();
},
// 点击,根据cfi值跳转
toMark(cfi) {
(cfi)
},
10.获取电子书信息
通过 book 中的 package 对象获取电子书信息:
- manifest 用来获取电子书的所有用到的文件信息;
- metadata 用来获取电子书的出版信息,其中 titile 为电子书的名字;
- ncxPath 为目录的路径;
- spine 为阅读顺序。
((meta) => {
("meta", meta);
= meta;
});
11.获取当前章节页码和总页数
获取当前章节页码和总页数与添加书签功能一样需要用到 rendition 对象中的 currentLocation 方法。
total:当前章节总页数;
page:当前页在当前章节页码。
showPage(page) {
const currentLocation = ();
("当前位置", {
...,
});
= {
total: page?.total || ,
page: page?.page || ,
};
},
总结
以上就完成了基于 epubjs 开发的基本的阅读器功能,样式和点击事件部分可以由各位根据需求来添加,如有问题和错误之处欢迎指出~
有宝子说 URL 未定义报错,我这里看了一下,可以通过使用 fetch 获取资源,然后将其转为 Blob 对象再使用。
= "/cloudstorage/";
const blob = await fetch().then((res) => ());
= new Epub(blob);