epubjs的基本使用
epubjs的基本使用
- 说道epub文件,其实说白了就是个压缩包,包含
html、css、img
等内容。 - 使用
epubjs
依赖jszip
库。通过传统方式引入勿要忘了引入jszip
。 - 通过现代脚手架,npm等方式包管理安装
epubjs
无需关心这一点。
基本安装与使用
传统
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
<script src="../dist/epub.min.js"></script>
或者
npm install epubjs
加载电子书
import Epub, { Book } from "epubjs"
let book:Book = Epub();
// 路径引入
book.open('https:/xxx.xx/url/demo.epub');
book.open('/url/demo.epub');
// 选择文件
const handleChangeFile = (e: any) => {
var file = e.target.files[0];
if (window.FileReader) {
var reader = new FileReader();
reader.onload = (r: any) => {
// 加载二进制
book.open(r.target.result, "binary");
};
reader.readAsArrayBuffer(file);
}
}
// 除了地址 binary 还支持 "base64","epub","opf","json","directory"等。
渲染图书
book
的位置可以使id选择器名称,也可以使element对象
// 滚动模式
book.renderTo("book", {
width: 960,
height:800,
flow: "scrolled",
allowScriptedContent: true,
});
// 默认执行下一页,追加下一页内容
// 增加 manager: "continuous", 滚动到底部自动追加下一页
// 分页
book.renderTo("book", {
width: "100vw",
height: "100vh", // 分页模式下 最好固定宽高
flow: "paginated",
spread: 'none', // none-单栏 both-两栏
allowScriptedContent: true,
});
// 移动端滑动分页 翻书的效果
book.renderTo("book", {
width: "100vw",
height: "100vh", // 分页模式下 最好固定宽高
snap:true, // 预加载
flow: "paginated",
manager: "continuous",
allowScriptedContent: true,
});
翻页
let rendition = book.renderTo(...);
// 默认显示第一页
rendition.display();
// 跳转到指定页
rendition.display(href);
// 下一页
rendition.next();
// 上一页
rendition.prev();
获取目录
book.loaded.navigation.then(doc => {
console.log(doc);
let menuList = doc.toc;
})
设置主题
/* themes.css */
.dark {
background: #000;
color: #fff
}
.light {
background: #fff;
color: #000;
}
.tan {
background: tan;
color: #ccc;
}
// 注册主题
rendition.themes.register("dark", "themes.css");
rendition.themes.register("light", "themes.css");
rendition.themes.register("tan", "themes.css");
// 选择主题
rendition.themes.select(theme);
设置文字大小
// 设置大小
rendition.themes.fontSize('22px');
// 设置百分比
rendition.themes.fontSize('120%');
选中文字进行高亮 划线 标记
import { Contents } from "epubjs"
rendition.on("selected", (cfiRange: string, contents: Contents) => {
// cfiRange 表示选中文字的范围
// 高亮
rendition.annotations.highlight(cfiRange, {
// 属性 例如 name:"name" -> data-name='name'
}, function() {
// 点击事件回调
}, 'className', {
// style
});
// 划线
rendition.annotations.underline(cfiRange, {}, function() { }, 'className', {});
// 标记
rendition.annotations.mark(cfiRange, {}, function() { }, 'className', {});
// 取消选中文字
contents.window.getSelection().removeAllRanges();
})
// 添加
rendition.annotations.add(cfiRange,'highlight|underline|mark')
// 取消
rendition.annotations.remove(cfiRange,'highlight|underline|mark')
cfiRange
字符可作为标识存储记录,利用这一点可和后端配合延伸笔记等功能- 设置高亮 划线 标记等是在dom同位置创建了svg,所以增加className为修饰svg元素。
判断当前选中区域是否存在已经选中过
// 记录已经选中并且标记的范围 数组
let cfiRangeArr = [];
const handleAddCf = (cfiRange: string): boolean => {
let cfiParts = cfiRange.split(',');
// 起始点
let _startCfi = cfiParts[0] cfiParts[1] ')';
// 终点
let _endCfi = cfiParts[0] cfiParts[2];
let EF = new EpubCFI();
for (let i = 0; i < efiarr.length; i ) {
let itemEf = efiarr[i];
let { startCfi, endCfi } = itemEf;
// 四个点
let s1_s2 = EF.compare(startCfi, _startCfi);
let e1_s2 = EF.compare(endCfi, _startCfi);
// 判断 后者的起始点是否在前者的区间内
if (s1_s2 == -1 && e1_s2 == 1 || s1_s2 == 0 || e1_s2 == 0) {
console.log("起始点在区间内");
return false;
}
let s1_e2 = EF.compare(startCfi, _endCfi);
let e1_e2 = EF.compare(endCfi, _endCfi);
if (s1_e2 == -1 && e1_e2 == 1 || s1_e2 == 0 || e1_e2 == 0) {
console.log("终点在区间内");
return false;
}
if (s1_s2 == -1 && e1_e2 == 1) {
console.log("不能在已经标记内容内选择");
return false;
}
if (s1_s2 == 1 && e1_e2 == -1) {
console.log("选择范围内包含了已经标记内容");
return false;
}
}
cfiRangeArr.push({
cfiRange,
startCfi: _startCfi,
endCfi: _endCfi
});
return true;
}
rendition.on("selected", (cfiRange: string, contents: Contents) => {
if (!handleAddCf(cfiRange)) {
contents.window.getSelection().removeAllRanges();
return;
}
// 进行标记
});
全文搜索 与 当前页搜索
全文搜索
const handleSearch = async (search:string) => {
let list:any[] = await Promise.all(
book.spine.spineItems.map(section => section.load(book.load
.bind(book))
.then(section.find.bind(section, search))
.finally(section.unload.bind(section)))
).then(results => Promise.resolve([].concat.apply([], results)))
console.log(list);
list.map((item) => {
let cfiRange = item.cfi;
})
}
当前页搜索
const handleSearch = (search:string) => {
let list: any[] = book.spine.get(current.value).find(search);
}
卸载
window.addEventListener("unload", function () {
console.log("unloading");
book.destroy();
});
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbegfg
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01