news 2026/2/11 18:04:58

[全栈实战] 从零打造一个“沉浸式”私人云端阅读器 (Node.js + EPUB.js)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[全栈实战] 从零打造一个“沉浸式”私人云端阅读器 (Node.js + EPUB.js)

在数字化阅读日益普及的今天,市面上的阅读软件层出不穷。但有时,我们只需要一个纯粹、无广告、可私有部署,且能完美适配手机单手操作的阅读器。

今天,我将分享如何使用Node.js作为后端,结合EJS模板引擎和强大的EPUB.js库,构建一个支持书架管理、阅读进度同步、高亮笔记、护眼模式的 Web 版电子书阅读器。

✨ 项目亮点

这个项目不仅仅是一个简单的文件查看器,它经过了多次迭代优化,具备了以下核心特性:

  1. 极简书架:自动扫描后台文件夹,支持搜索,包含“最近阅读”和“收藏夹”功能。
  2. 沉浸式阅读:去除了所有多余元素,采用“羊皮纸”护眼色调,字体强制优化(解决 EPUB 自带样式乱码问题)。
  3. 单手操作优化:针对移动端设计,屏幕左右边缘点击翻页,中间区域用于长按选词。
  4. 无数据库设计:利用浏览器的LocalStorage存储阅读进度、笔记和收藏状态,部署极其简单(即插即用)。
  5. 完整交互:支持底部滑块快速跳转、滑动翻页动画、高亮划线及笔记管理。

🛠 技术栈

  • 后端:Node.js + Express (处理路由和文件扫描)
  • 文件上传:Multer
  • 模板引擎:EJS (服务端渲染 HTML 结构)
  • 核心库:EPUB.js (解析和渲染电子书)
  • 样式:原生 CSS3 (Grid 布局 + Flexbox)
  • 图标库:LineIcons

🏗️ 核心实现解析

1. 后端:极简的文件服务

后端的逻辑非常轻量。我们不需要复杂的数据库,只需要扫描public/uploads文件夹下的.epub文件即可生成书架。

// app.js 核心逻辑app.get('/',async(req,res)=>{// 扫描文件夹letfiles=awaitfs.readdir(uploadDir);// 过滤 epub 文件letbooks=files.filter(f=>f.toLowerCase().endsWith('.epub'));// 简单的按文件名搜索if(req.query.q){books=books.filter(book=>book.toLowerCase().includes(req.query.q.toLowerCase()));}// 渲染 EJS 模板res.render('index',{books,query:req.query.q});});

这种设计意味着你可以直接通过 FTP 或系统文件管理器把几百本电子书丢进文件夹,刷新网页就能看。

2. 前端:解决“乱码”与“护眼”

很多 EPUB 电子书自带了千奇百怪的 CSS(比如黑色背景、极小的字体)。为了保证统一的阅读体验,我使用了EPUB.jshooks功能,在电子书渲染时强制注入自定义样式。

// reader.ejsrendition.hooks.content.register(function(contents){constdoc=contents.document;consthead=doc.querySelector('head');consts=doc.createElement('style');// 强制覆盖样式,实现护眼模式s.innerHTML=`body { font-family: 'Georgia', serif !important; font-size: 19px !important; line-height: 1.8 !important; color: #4a3b2a !important; /* 深褐色文字 */ background-color: #f7f1e3 !important; /* 米黄色背景 */ padding: 0 10px !important; text-align: justify !important; } img { max-width: 100% !important; }`;head.appendChild(s);});

3. 交互:解决移动端痛点

在手机上开发 Web 阅读器最大的挑战是触摸冲突。我们需要区分“点击翻页”、“滑动翻页”和“长按选词”。

我的解决方案是:

  • 左右边缘 20%:放置透明的div(.nav-zone),点击触发展示上一页/下一页。
  • 中间区域:留给用户直接操作文字(用于长按高亮)。
  • 底部滑块:为了防止滑块拖动时页面疯狂跳转,我们监听input事件只更新数字,监听change事件(松手后)才真正执行跳转。
// 底部滑块逻辑优化slider.addEventListener('input',(e)=>{// 拖动时只更新显示的百分比文字document.getElementById('page-info').innerText=Math.floor(e.target.value/10)+"%";});slider.addEventListener('change',(e)=>{// 松手后,才进行计算资源密集的跳转if(book.locations.length()>0){rendition.display(book.locations.cfiFromPercentage(e.target.value/1000));}});

4. 数据存储:巧妙利用 LocalStorage

为了让项目部署极其简单(不需要配置 MySQL 或 MongoDB),所有的用户数据(收藏列表、阅读进度 CFI、笔记内容)都存储在浏览器的localStorage中。

  • 进度记忆:监听relocated事件,将当前的 CFI (EPUB 的定位标识) 存入本地。
  • 收藏夹:在首页通过 JS 读取本地数组,动态将喜欢的书克隆到“收藏区”。
// 笔记数据结构示例constnote={id:172839201,cfi:"epubcfi(/6/14[chapter1]!/4/2/1:0)",// 精确的定位text:"被选中的原文内容",note:"这是我的读后感...",date:"2023/10/01"};// 存入 localStorage

🎨 UI 设计细节

为了达到“美观易用”的标准,CSS 方面做了很多细微的调整:

  1. Grid 布局书架:使用了grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));,这使得书架在宽屏电脑和窄屏手机上都能自动完美排列。
  2. 层级管理 (Z-Index):书架卡片上有一个“爱心”按钮。为了防止点击爱心时误触进入书籍,我们将爱心按钮的z-index设为 10,将书籍链接层设为 1,完美分离了点击事件。
  3. 长标题处理:使用-webkit-line-clamp: 2限制书名最多显示两行,保持了界面的整洁统一。

🚀 如何运行本项目

  1. 初始化项目
    mkdirmy-reader&&cdmy-readernpminit-ynpminstallexpress multer ejs fs-extra
  2. 创建文件结构:按照源码建立app.js,views/,public/等目录。
  3. 启动
    nodeapp.js
  4. 访问
    • PC 端访问http://localhost:3000
    • 手机端访问http://你的电脑IP:3000(需在同一 WiFi 下)

📝运行界面

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/8 21:22:31

AMD调试工具终极指南:彻底释放Ryzen处理器性能潜力

AMD调试工具终极指南:彻底释放Ryzen处理器性能潜力 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gitco…

作者头像 李华
网站建设 2026/2/2 23:23:27

Sunshine云游戏革命:打破设备界限的全新游戏体验

Sunshine云游戏革命:打破设备界限的全新游戏体验 【免费下载链接】Sunshine Sunshine: Sunshine是一个自托管的游戏流媒体服务器,支持通过Moonlight在各种设备上进行低延迟的游戏串流。 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine …

作者头像 李华
网站建设 2026/2/7 8:43:27

Sunshine游戏串流终极指南:打造个人专属云游戏平台

Sunshine游戏串流终极指南:打造个人专属云游戏平台 【免费下载链接】Sunshine Sunshine: Sunshine是一个自托管的游戏流媒体服务器,支持通过Moonlight在各种设备上进行低延迟的游戏串流。 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine …

作者头像 李华
网站建设 2026/2/7 14:22:49

Tailwind按需引入:AI配置PurgeCSS清除未使用类

Tailwind按需引入:AI配置PurgeCSS清除未使用类 在现代前端工程中,一个看似微不足道的决策——是否启用 CSS 按需引入——往往能决定页面首屏加载是流畅还是卡顿。Tailwind CSS 作为近年来最受欢迎的原子化框架之一,以其“实用类优先”的理念极…

作者头像 李华
网站建设 2026/2/11 3:31:38

艾尔登法环帧率解锁工具完整使用指南

艾尔登法环帧率解锁工具完整使用指南 【免费下载链接】EldenRingFpsUnlockAndMore A small utility to remove frame rate limit, change FOV, add widescreen support and more for Elden Ring 项目地址: https://gitcode.com/gh_mirrors/el/EldenRingFpsUnlockAndMore …

作者头像 李华