<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"> <title>EPUB</title> <script src="https://cdn.bootcdn.net/ajax/libs/jszip/3.1.5/jszip.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/epubjs@0.3.88/dist/epub.min.js"></script> <script> document.addEventListener('DOMContentLoaded', () => { const html = document.querySelector('html') let fontSize = window.innerWidth / 10 fontSize = fontSize > 50 ? 50 : fontSize html.style.fontSize = fontSize + 'px' }) </script> <style> * { padding: 0; margin: 0; } .mask { position: absolute; display: flex; left: 0; width: 100%; height: 100%; flex-direction: column; } .meun { display: flex; height: 1rem; align-items: center; } #toc { flex: 1; z-index: 100; font-size: .3rem; padding-left: .4rem; color: #333; } #page { z-index: 100; font-size: .3rem; color: #333; padding-right: 0.4rem; text-align: right; flex: 0 0 .5rem; } #load { z-index: 100; font-size: .3rem; color: #333; padding-right: 0.4rem; text-align: right; flex: 0 0 .5rem; } #toc-content { position: absolute; display: flex; top: 0; right: 0; z-index: 102; min-width: auto; max-width: 80%; height: 100%; background: white; flex-direction: column } #toc-mask { position: absolute; top: 0; left: 0; z-index: 101; width: 100%; height: 100%; background: rgba(51, 51, 51, .8); } .intro { width: 100%; height: 2.4rem; padding: .2rem .4rem; box-sizing: border-box; height: 3rem; display: flex; border-bottom: .1rem solid #f4f4f4; } .txt { display: flex; flex: 1; align-items: center; padding: 0 .2rem; font-size: .3rem; } #content { overflow-y: auto; } .item { padding: .2rem .4rem; border-bottom: .07rem solid #f4f4f4; font-size: .4rem; color: #333; } #open { display: flex; flex: 1; z-index: 100; font-size: .4rem; color: #333; align-items: flex-end; justify-content: center; } #open span { padding: .3rem .3rem; border: .05rem solid #333; border-radius: .2rem; } .read { display: flex; flex: 1 1 auto; } #prev { flex: 0 0 2rem; z-index: 100; } #viewer { flex: 1; } #next { flex: 0 0 2rem; z-index: 100; } .save { display: flex; } .box { padding: .2rem .2rem; justify-content: center; border-bottom: .1rem solid #f4f4f4; } .jump { display: flex; height: 1rem; border-bottom: .1rem solid #f4f4f4; } .jump input { flex: 1; padding: .1rem .1rem; margin: .2rem .2rem .2rem .4rem; outline: none; font-size: .3rem; } .jump span { flex: 0 0 1rem; } </style> </head> <body> <div id="ebook"> <div class="mask"> <div id="open"> <span onclick="document.getElementById('input').click();document.getElementById('open').style.display = 'none'">选择本地书籍</span> <input type="file" id="input" style="display: none;"> </div> <div class="read"> <div id="prev" onclick="rendition.prev()"></div> <div id="viewer"></div> <div id="next" onclick="rendition.next()"></div> </div> <div class="meun"> <div id="toc" onclick="showhide()"></div> <div id="page"></div> <div id="load"></div> </div> <div id="toc-mask" style="display: none;" onclick="showhide()"></div> <div id="toc-content" style="display: none;"> <div class="intro"> <img id="cover"> <div style="display: flex;flex: 1;flex-direction: column;overflow-y: auto;"> <div id="title" class="txt"></div> <div id="author" class="txt"></div> <div id="publisher" class="txt"></div> <div id="pubdate" class="txt"></div> </div> </div> <div class="save"> <div class="txt box" onclick="save()">存档</div> <div class="txt box" onclick="get()">读档</div> <div class="txt box" onclick="del()">删档</div> </div> <div class="jump"> <input id="jump" type="number" placeholder="0-1之间的数字,如0.25" oninput="if(value>1)value=1;if(value<0)value=0"> <span class="txt" onclick="jump()">跳转</span> </div> <div id="content"></div> </div> </div> </div> <script> let url = location.search.substring(3); if (url !== "") { var book = ePub(url); document.getElementById("open").style.display = "none" } else { var book = ePub(); var inputElement = document.getElementById("input"); inputElement.addEventListener('change', function (e) { var file = e.target.files[0]; if (window.FileReader) { var reader = new FileReader(); reader.onload = openBook; reader.readAsArrayBuffer(file); } }); function openBook(e) { var bookData = e.target.result; book.open(bookData, "binary"); } } //渲染 var rendition = book.renderTo("ebook", { with: window.innerWidth, height: window.innerHeight - 20 }); rendition.display(); book.ready .then(() => { var local = localStorage.getItem(book.key() + '-locations'); if (local) { return book.locations.load(local); } else { return book.locations.generate(); } }) .then(locations => { localStorage.setItem(book.key() + '-locations', book.locations.save()); }) // 目录 book.loaded.navigation.then(toc => { var read = localStorage.getItem(book.key() + '-read'); if (read) { rendition.display(read); } var $content = document.getElementById("content"); toc.forEach(item => { var div = document.createElement("div"); div.className = "item"; div.textContent = item.label; div.addEventListener("click", () => { rendition.display(item.href); showhide() }); $content.appendChild(div) }) }) //简介 book.loaded.metadata.then(meta => { var $title = document.getElementById("title"); var $author = document.getElementById("author"); var $cover = document.getElementById("cover"); var $publisher = document.getElementById("publisher"); var $pubdate = document.getElementById("pubdate"); $title.textContent = `书名:${meta.title}`; $author.textContent = `作者:${meta.creator}`; $publisher.textContent = `出版社:${meta.publisher}`; $pubdate.textContent = `时间:${meta.pubdate}`; if (book.archive) { book.archive.createUrl(book.cover) .then(url => { $cover.src = url; }) } else { $cover.src = book.cover; } }); //进度显示 rendition.on('relocated', location => { var percent = book.locations.percentageFromCfi(location.start.cfi); var $page = document.getElementById("page"); var $load = document.getElementById("load"); $page.textContent = location.end.displayed.page + '/' + location.end.displayed.total; $load.textContent = Math.fround(percent * 100).toFixed(1) + '%'; }) //章节名显示 rendition.on("rendered", section => { var $toc = document.getElementById("toc"); $toc.textContent = "目录"; $toc.textContent = book.navigation.get(section.href).label; }) function showhide() { var $toc_content = document.getElementById("toc-content") var $mask = document.getElementById("toc-mask") if ($toc_content.style.display == "none") { $toc_content.style.display = "" $mask.style.display = "" } else { $toc_content.style.display = "none" $mask.style.display = "none" } } function jump() { $jump = document.getElementById("jump").value; rendition.display(book.locations.cfiFromPercentage($jump)); showhide(); document.getElementById("jump").value = ""; } function save() { localStorage.setItem(book.key() + '-read', rendition.currentLocation().start.cfi) showhide() } function get() { rendition.display(localStorage.getItem(book.key() + '-read')); showhide() } function del() { localStorage.removeItem(book.key() + '-read'); showhide() } </script> </body> </html>