三、阅读器开发--4、阅读器目录、全文搜索功能开发
1、阅读器目录
1.1、实现目录
先实现目录的布局
定义一个蒙版,充满整个屏幕浮在阅读器上方,左侧为目录右侧为背景,目录下方包含一个tab,点击后会切换不同的内容,这里tab是目录、书签,这里可以通过如下的vue的动态组件机制来实现组件的动态切换
这个tab我们可以放到蒙版组件中,上方的目录信息可以单独作为一个组件,同样书签也可以单独封装成一个组件,初次加载的动画也封装成一个组件。接下来我们就开始实现
实现tab
然后实现我们的tab组件的选中状态高亮,我们data中定义一个变量currentTab为1时目录高亮,为2时书签高亮,所以给书签和目录这两个div绑定一个class,如果currentTab===1则目录的有selected样式,为2则书签有selected样式即高亮
然后点击切换哪一个哪一个就高亮,所以都绑定一个点击事件,如下
动态组件做目录、书签那部分
然后目录书签那部分空间,目录、书签我们都分别单独做成一个组件,也就是那部分空间有时候是展示目录组件有时候就展示书签组件,也就是我们上面讲的动态组件,我们通过<component :is=""></component>来做,如下currentTab如果为1则展示content组件,如果为2则展示bookmark组件
下面我们来创建这两个组件即如下EbookSlideContents和,并且引入到EbookSlide组件中
然后我们来做这个目录组件
我们先来实现上方搜索框
我们是用input做的输入框,type为text,placeholder是提示文字。flex布局即display:flex中flex:0 0 50px;即不放大不缩小宽度50px,flex:1;即把剩余的空间自动填充满。
但是我们点击搜索的时候,会出现如下的搜索框,这个要处理掉,通过伪类outline:none实现
下面我们再来实现取消的事件:当点击搜索框时,取消按钮应该出现,点击取消按钮时,取消按钮应该消失,所以我们定义一个变量searchVisible来控制取消按钮是否显示,给取消按钮点击事件,点击取消按钮则隐藏取消按钮,给搜索框添加点击事件,点击搜索框则隐藏取消按钮,如下
然后做中间图书和已读时间的布局

然后我们需要先去获取电子书封面、内容这些信息,所以要回到EbookReader中在电子书解析时即initEpub中获取
但是此时cover还不是一个链接,我们需要把它变成一个url,然后存到vuex中,如下
这里做的时候发现封面一直渲染不出来,找了好久,明明路径也对,nginx服务器中也有cover文件夹,最后发现是漏了下面这个冒号,哎呀
我们先再去获取标题作者信息这些
然后通过css把封面大小调整好,下面这个是标题的展示样式:
然后接下来我们就搞目录啦
首先我们来获取目录数据,同理到EbookReader中获取电子书目录信息。我们可以看到navigation下toc即为一级目录,第0个其中的subitems即为这个一级目录下的子目录即二级目录,二级目录里面的subitems可能还有三级目录等,然后还有parent表示它的父级目录,label表示目录内容,href表示路径,通过把这个路径传入display方法即可实现对电子书进行渲染,然后display方法中做定位显示
然后这里有一个难点,就是如何将获取过来的树状的数据结构转化为列表那种一维的结构,正确的做法是将树状的这个Array转化为一维的数组。
先解释一下:
先用扩展运算符...[xxx] 把树状结构打散,然后用concat进行合并,即可完成把上面树状结构转化为一维数组如下图这样子
扩展运算符,扩展运算符可以对数组做拆分操作。树状结构是如下图那个样子,用扩展运算符如打印‘ ...[1,2] ’那么得出的结果是1 2,可以看到输出 1,2 ,即被拆开了拆成了两个数。这个概念是非常重要的
我们拆分后,我们再将它们合并,又是一个概念叫concat,concat可以将拆分后的分散的元素进行合并,合并到你指定的数组中。比如打印[0].concat(...[1,2]),这是指将[1,2]这个数组拆开,用一个数组[0],调用concat方法进行合并到这个数组中,最终结果是[0,1,2],但是这个还只能做到二级,还不能打散到下面的三四级
我们写一个方法,方法中传入这个数组,然后map遍历这个数组,并且递归进去打散重组,即每个item都自己和自己孩子打散再重组,即[1,递归进2和5] ,2又递归进3和4,最后递归出来就是:先 3,4打散重组得[3,4],然后2和2孩子们打散重组得 [ 2,[3,4] ] ,然后1和1孩子们打散重组得[ [1,[2,[3,4]],5] , 6 ] ,即可得到最终如下图的结果
所以我们把这个方法封装到utils下的book.js中
哇靠这里写多了一个{},哇后面转换出的一维数组就都是undefined了,小心啊哇靠,
举个例子看看使用flatten前后:
就能看到结果为
然后EbookReader中引入,可以看到如下
有了上面这个目录之后,我们就去判断它的level,即当前目录为哪一层,但是其中并没有level属性,所以并不知道当前是一级目录还是二级目录,不过它给了我们parent,所以我们可以通过parent来判断。
由于没有给层级,所以我们自己给每个目录添加层级level属性,以便后面区分是否缩进。
根据它的父级是谁从而判断它是几级目录,为undefined即为一级目录;如果父级是存在的,那么就去判断它的父级是不是一级目录,如果它的父级是一级目录那么它就是二级目录;如果它是三级目录四级目录就不怎么容易判断了。所以在扁平化处理后,我们定义一个函数给每个item添加一个层级level属性。这样就能知道这个目录是第几级目录了
如下,forEach去循环,给每一个item加一个level属性=通过find去查询它属于第几级,默认为0级即一级。定义find函数,如果item的父级不存在,则返回level即level为0是一级目录;如果它父级存在,就继续find,把它的父级找出来看看它的父级的父级是什么等级,并且此时等级要加1(比如三级那个3,它父级有是2则3的等级0+1=1,再找2的父级,发现2有父级1,则3等级再+1=2,再找1的父级发现是undefined所以3的等级不再加1了,返回3的等级即等级为2,所以3是三级目录)
举例如下树状结构,变成一维数组,再往一维数组中每一个元素添加level
结果如下
所以最终项目中是如下
如上就处理好了数据,然后我们就把处理好的值放到vuex中
处理好了目录数据后,接下来我们就来实现目录的列表
准备滚动条组件
我们在component下建一个common文件夹,这里放一些通用的组件,我们做一个滚动条组件叫Scroll.vue。滚动条组件中有插槽,我们在目录组件中用<scroll></scroll>包起来的就会被放到这里;然后滚动条组件中如下接收top和bottom,即滚动条距离顶部和底部的距离;滚动条滚动时定义下面那个handleScroll方法,方法中滚动条滚动了就去调用目录组件中的onScroll方法并且把滚动的偏移量传过去。
再加个如下的工具方法,计算高度的时候用
然后我们回到目录组件中,把滚动条组件引入,滚动条组件中我们要指明top和bottom,以便帮我们自动计算宽高
然后我们来填充滚动条里面的内容

然后我们样式调整一下
二级目录三级目录咋缩进呢,用一个动态style绑定一个方法,方法中根据level来算
但是二级目录没有缩进,我们就给它绑定一个style,style跟一个方法,这个方法中返回一个margin-left样式,样式大小就根据它level*15来算,如下
然后实现当前目录高亮显示
我们需要去判断当前章节与我们目录的位置是否一致,我们之前vuex中有一个section章节,0表示第一章节,1表示第二章节,然后section与我们这里循环的时候的index刚好是一样的,我们就绑定一个class,如果section与当前index相等则说明是正在阅读的章节,咱闷就给个selected样式即高亮
然后我们实现点击事件
点击后我们就去渲染点击章节的内容嘛,那么就是去调minxin中的display方法,我们获取目录的时候那个navigation就有href即目录章节的路径,把路径传进display中即可实现渲染当前章节了
1.2、接下来实现全文搜索功能
全文搜索算法官方已经提供给我们了,在epubjs源码地址下wiki中有那个doSearch方法。
我们复制放到目录方法中,先定搜added,看看能不能返回搜索结果,如下我们在mounted钩子函数中去调用这个方法,可以看到有搜索结果回来
我们搜索的时候图书列表和目录是不展示的,所以给个v-show也就是searchVisible为false的时候展示
searchVisible为true的时候展示搜索列表,如下
然后将搜索文本与搜索框绑定,这样就可以实现双向数据绑定
搜索列表去循环搜索结果列表,其中的excerpt就是要展示的
取消的时候清空搜索框里的内容以及搜索列表中的内容,让请求回来的结果给searchList
给样式
最终
现在我们做事件绑定,完成我们输入内容和搜索结果的匹配
给搜索框定义一个键盘按下去的事件.enter就是点击enter键的意思
然后我们给关键字加入高亮显示
但是还是没高亮成功,因为如下这种方式会把item.excerpt解析为文本,我们应该使用v-html,将item.excerpt作为html内容载入
如下,就实现了高亮
最后我们做点击事件,点击搜索出来的可以渲染当前页面内容出来
我们前面看到了搜索返回的数据是有内容excerpt还有一个cfi的,所以我们可以把这个cfi传入display即可实现渲染
到此目录和搜索功能就实现完成了
相关文章:

三、阅读器开发--4、阅读器目录、全文搜索功能开发
1、阅读器目录 1.1、实现目录 先实现目录的布局 定义一个蒙版,充满整个屏幕浮在阅读器上方,左侧为目录右侧为背景,目录下方包含一个tab,点击后会切换不同的内容,这里tab是目录、书签,这里可以通过如下的…...

AMEYA360代理 | 江苏长晶科技FST2.0高性能 IGBT产品介绍
江苏长晶科技股份有限公司是一家专业从事半导体产品研发、生产和销售的企业。自2019年起,连续4年被中国半导体行业协会评为 “功率器件十强企业”。2021年开始自主研发有着“工业CPU”之称的IGBT,截至2023年Q3在家电/工业/新能源等行业实现8款产品市场应…...

基于springboot+vue+Mysql的网上图书商城
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...

阿里云服务器多少钱一个月?低至5元1个月
阿里云服务器一个月多少钱?最便宜5元1个月。阿里云轻量应用服务器2核2G3M配置61元一年,折合5元一个月,2核4G服务器30元3个月,2核2G3M带宽服务器99元12个月,轻量应用服务器2核4G4M带宽165元12个月,4核16G服务…...
LeetCode第五天(442. 数组中重复的数据)
给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回。 你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问…...
chatgpt正面案例合集
现在可以用百度 百度安全验证 chatgpt用来搜索软件使用指令太牛了_个人渣记录仅为自己搜索用的博客-CSDN博客 chatgpt 使用案例 根据不同的目标群体变更文案和表达_个人渣记录仅为自己搜索用的博客-CSDN博客 倾听能力 和哪些基础能力相关 ,如何提高 chatgpt_个人渣记录仅为自…...
今日讲讲路由配置
下载安装路由 1. 下载安装路由库 npm i vue-router 2. 在 src 中新建 views 文件夹,在其中新建页面 3. 在 src 中新建一个 router 文件夹,其中新建一个 index.js import { createRouter, createWebHashHistory } from vue-router; // 导入页面 imp…...
【Rust】Shared-State Concurrency
Shared-State Concurrency channel类似于single ownership. 而shared memory类似与multiple ownership. multiple ownership是难于管理的. smarter pointer也是multiple ownership的. Rust的type system和ownership rules帮助实现正确的multiple ownership管理。 Using Mute…...

连接数据库(MySQL)的JDBC
目录 JDBC简介快速入门API详解DriverManager(驱动管理类)注册驱动:获取数据库连接(对象): Connection(数据库连接对象)获取执行SQL的对象管理事务 Statement(执行SQL语句)执行DML、DDL语句执行DQL语句 Resu…...
golang通过参数控制HTTP server是否使用基本认证
之前写的《golang实现一个BasicAuth的HTTP server》一定会做基本认证。 本例给出了如何通过启动时候指定的参数来控制是否做基本认证 代码对比和解释 给出与上一篇中源码的diff adminhpc-1:~/go/auth_http$ diff -ruN http_rpc_server.go_bak http_rpc_server.go --- http_rp…...

javaSwing坦克大战游戏
在游戏开发领域,坦克大战是一款经典的游戏,其简单而又耐玩的玩法吸引了无数玩家。而今,在Java编程技术的支持下,我们可以用Java Swing技术轻松实现这款经典游戏。本文将介绍如何使用Java Swing技术编写坦克大战游戏,并…...

【面试题】数据底层原理:Elasticsearch写入流程解析
前言:本篇博客将介绍Elasticsearch的数据底层原理,涉及数据写入的过程以及相关概念。我们将深入探讨buffer、translog、refresh、commit、flush和merge等核心概念,帮助您更好地理解Elasticsearch的数据存储机制。 写入数据的基本过程 Elast…...
牛客论坛spring initializer选用的构件
spring版本:2.1.5.RELEASE java版本:8 pom文件: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-i…...

【Java程序设计】【C00385】基于(JavaWeb)Springboot的员工信息管理系统(有论文)
基于(JavaWeb)Springboot的员工信息管理系统 项目简介项目获取开发环境项目技术运行截图 博主介绍:java高级开发,从事互联网行业六年,已经做了六年的毕业设计程序开发,开发过上千套毕业设计程序,…...

【Linux进阶之路】理解UDP,成为TCP。
前言 学了TCP 和UDP之后,感觉UDP就像是初入职场的年轻人,两耳不闻 “窗外事”,只管尽力地把自己的事情做好,但收获的却是不可靠,而TCP更像是涉世极深的"职场老油条",给人的感觉就是 “城府极深&a…...

Linux实用操作
一,各类小技巧(快捷键) 强制停止 ctrlc强制停止 Linux某些程序的运行,如果想要强制停止它,可以使用快捷键ctrlc 命令输入错误,也可以通过快捷键ctrlc,退出当前输入,重新输入 退出、登出 ctrld退出或登出 可以通过快…...
OpenJudge - 12:加密的病历单
总时间限制: 1000ms 内存限制: 65536kB 描述 小英是药学专业大三的学生,暑假期间获得了去医院药房实习的机会。 在药房实习期间,小英扎实的专业基础获得了医生的一致好评,得知小英在计算概论中取得过好成绩后,主任又额外交给她一…...
QGIS编译(跨平台编译)057:FastCGI编译(Windows、Linux、MacOS环境下编译)
文章目录 1、FastCGI介绍2、FastCGI下载3、Windows下编译4、linux下编译5、MacOS下编译1、FastCGI介绍 FCGI 是 FastCGI 的缩写,是一种用于改善 CGI(Common Gateway Interface)性能的协议。在传统的 CGI 中,每次请求都需要启动一个新的进程来处理,这导致了较高的资源消耗和…...

jenkins+newman+postman持续集成环境搭建
一、Newman简介 Newman是一款基于Node.js开发的,可以运用postman工具直接从命令运行和测试postman集合 二、Newman应用 环境准备:js/ cnpm或npm配置好环境,执行如下命令 三、安装newman 验证是否安装成功,命令:newm…...
取消自动设置的开机自启动(pywin32库)请勿仿照!否则可能对电脑造成损害。
本文使用创作助手。 要取消Python程序的开机自启动,可以通过删除注册表中相应的注册表项来实现。请按照以下步骤进行操作: 打开Windows注册表编辑器:按下 Windows R 键,输入 regedit,然后按下回车键。 导航到注册表…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...

认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...
TCP/IP 网络编程 | 服务端 客户端的封装
设计模式 文章目录 设计模式一、socket.h 接口(interface)二、socket.cpp 实现(implementation)三、server.cpp 使用封装(main 函数)四、client.cpp 使用封装(main 函数)五、退出方法…...

高分辨率图像合成归一化流扩展
大家读完觉得有帮助记得关注和点赞!!! 1 摘要 我们提出了STARFlow,一种基于归一化流的可扩展生成模型,它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流(TARFlow&am…...