使用epub.js解析epub文件(电子书)

使用epub.js解析epub文件(电子书)

首先什么是 epub 呢?

ePub(Electronic Publication 的缩写,意为:电子出版),是一个自由的开放标准,属于一种可以“自动重新编排”的内容;也就是文字内容可以根据阅读设备的特性,以最适于阅读的方式显示。EPub 档案内部使用了 XHTML 或 DTBook (一种由 DAISY Consortium 提出的 XML 标准)来展现文字、并以 zip 压缩格式来包裹档案内容。EPub 格式中包含了数位版权管理(DRM)相关功能可供选用。
EPUB 解决了 PDF 和开发人员友好性有关的所有瑕疵。一个 EPUB 就是一个简单 ZIP 格式文件(使用 .epub 扩展名),其中包括按照预先定义的方式排列的文件。除此以外,EPUB 非常简单:
1、epub 中的所有内容基本上都是 XML。EPUB 文件可使用标准 XML 工具创建,不 1 需要任何专门或者私有的软件。
2、EPUB 内容(eBook 的具体内容)基本上都是 XHTML 1.1(另一种格式是 DTBook,为视力受限者编码书籍的一种标准。关于 DTBook 的更多信息请参阅参考资料,本教程中不涉及这部分)。
3、大多数 EPUB XML 模式都来自现成的、可免费获得的、已发布的规范。
最关键的在于 EPUB 元数据是 XML,EPUB 内容是 XHTML。如果您的文档构建系统产生的结果用于 Web 和/或基于 XML,那么也可用于生成 EPUB。以 Google、apple 为代表的众多公司都以 epub 作为数字图书的格式.
以上内容来意百度知道。

那我们前端用什么来解析 epub 呢?

正如标题所说,现在已经有现成的类库可以实现 epub 的解析,那就是 epub.js.Github 地址:https://github.com/futurepress/epub.js

现在来看看怎么用吧

  1. 首先准备一个 epub 文件(网上一大堆)。
1
const DOWNLOAD_URL = "static/Linux_Book.epub";
  1. 解析电子书,生成 Book 对象
1
const book = new Epub(DOWNLOAD_URL);
  1. 通过 Book.renderTo 生成 Rendition 对象(对象名不唯一)
1
2
3
4
5
6
7
// 第一个参数是容器(div)的id
const rendition = book.renderTo("read", {
// 宽度
width: window.innerWidth,
// 高度
height: window.innerHeight,
});
  1. 通过 Rendtion.display 渲染电子书
1
rendition.display();
  1. 获取 Theme 对象
1
const themes = rendition.themes;
  1. 设置默认字体
1
2
// 参数为字体大小
themes.fontSize(fontSize + "px");
  1. 主题注册
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
themes.register(themeName, themeStyle);
/**
* 例如:
const themeList = [
{
name: "default",
style: {
body: {
color: "#000",
background: "#fff",
},
},
},
{
name: "eye",
style: {
body: {
color: "#000",
background: "#ceeaba",
},
},
},
{
name: "night",
style: {
body: {
color: "#fff",
background: "#000",
},
},
},
{
name: "gold",
style: {
body: {
color: "#000",
background: "rgb(241,236,226)",
},
},
},
];

themeList.forEach((theme) => {
// 注册全部主题颜色样式
this.themes.register(theme.name, theme.style);
});
* /
  1. 主题切换
1
2
// 参数为主题名称
themes.select(themeName);
  1. 获取 Locations 对象-通过 epubjs 钩子函数来实现电子书定位
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
let navigation;
let locations;
book.ready.then(() => {
// 生成目录
navigation = this.book.navigation;
/**
* navigation就是目录对象
* 他的结构为:
* {
* landmarks:Array,
* landmarksByType:Object,
* length:Number,
* toc:Array,
* tocByHref:Object,
* tocById:Object
* }
* 其中里面的toc就是我们需要的目录列表了
* toc的结构为一个json数组,其中每一个的结构为:
* {
* href:String, // 目录跳转的链接
* id:String, // 目录ID
* label:String, // 目录名称
* parent:undefined,// 父级目录
* subitems:Array // 目录下的子目录
* }
* /
// console.log(this.navigation);
return book.locations.generate();
})
.then(result => {
locations = book.locations;
// this.onProgressChange(50); //实现跳转到百分之50的位置
// 到这里书籍目录就加载完毕了
});
},
  1. 翻页功能(封装为方法)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 翻页功能
// 下面的rendition在上面已经获取了
prevPage() {
// rendition.prev方法实现上一页
if (rendition) {
rendition.prev();
}
}
nextPage() {
// rendition.next方法实现下一页
if (rendition) {
rendition.next();
}
},
  1. 拖动进度条功能(封装为方法)
1
2
3
4
5
6
7
8
// propress进度条的数值(0-100)
onProgressChange(progress) {
const percentage = progress / 100;
const location =
percentage > 0 ? this.locations.cfiFromPercentage(percentage) : 0;
// rendition上面已经获取到了
rendition.display(location);
},
  1. 根据链接跳转到指定位置(目录)
1
2
3
4
jumpTo(href) {
// rendition上面已经获取到了
rendition.display(href);
}

可监听事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
export const EPUBJS_VERSION = "0.3";

// Dom events to listen for
export const DOM_EVENTS = ["keydown", "keyup", "keypressed", "mouseup", "mousedown", "click", "touchend", "touchstart", "touchmove"];

export const EVENTS = {
BOOK : {
OPEN_FAILED : "openFailed"
},
CONTENTS : {
EXPAND : "expand",
RESIZE : "resize",
SELECTED : "selected",
SELECTED_RANGE : "selectedRange",
LINK_CLICKED : "linkClicked"
},
LOCATIONS : {
CHANGED : "changed"
},
MANAGERS : {
RESIZE : "resize",
RESIZED : "resized",
ORIENTATION_CHANGE : "orientationchange",
ADDED : "added",
SCROLL : "scroll",
SCROLLED : "scrolled",
REMOVED : "removed",
},
VIEWS : {
AXIS: "axis",
WRITING_MODE: "writingMode",
LOAD_ERROR : "loaderror",
RENDERED : "rendered",
RESIZED : "resized",
DISPLAYED : "displayed",
SHOWN : "shown",
HIDDEN : "hidden",
MARK_CLICKED : "markClicked"
},
RENDITION : {
STARTED : "started",
ATTACHED : "attached",
DISPLAYED : "displayed",
DISPLAY_ERROR : "displayerror",
RENDERED : "rendered",
REMOVED : "removed",
RESIZED : "resized",
ORIENTATION_CHANGE : "orientationchange",
LOCATION_CHANGED : "locationChanged",
RELOCATED : "relocated",
MARK_CLICKED : "markClicked",
SELECTED : "selected",
LAYOUT: "layout"
},
LAYOUT : {
UPDATED : "updated"
},
ANNOTATION : {
ATTACH : "attach",
DETACH : "detach"
}
}

epubjs:API document :https://github.com/futurepress/epub.js/blob/master/documentation/md/API.md

Rendition:APIs:setManager()方法:设置渲染方式requireManager()next()prev()flow();getContents()hooks()annotationns()location()themes()views()

epub Hook:this.content = new EPUBJS.Hook(this);
Layout:flow() flow string paginated | scrolled用于切换翻页方式,浏览方式

Themes:font();
Annotations:【注解、批注的意思】

EpubCFI:

pageList:


使用epub.js解析epub文件(电子书)
https://www.shaohang.xin/2020/08/31/technical/javascript/epub-js/
作者
少航
发布于
2020年8月31日
许可协议