三、阅读器开发--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即可实现渲染

到此目录和搜索功能就实现完成了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/493687.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为设备配置攻击防范

组网需求 如图1所示&#xff0c;如果局域网内存在Hacker向RouterA发起畸形报文攻击、分片报文攻击和泛洪攻击&#xff0c;将会造成RouterA瘫痪。为了预防这种情况&#xff0c;管理员希望通过在RouterA上部署各种攻击防范措施来为用户提供安全的网络环境&#xff0c;保障正常的…

【Canvas与艺术】模拟八一电影制片厂电影片头效果

【缘起】 八一厂每部电影前都有其专有开头&#xff0c;如&#xff1a;https://www.ixigua.com/6799821997258834440?logTag2eacce76401e13f9efe7 这个片头可以用canvas模拟下来。 【关键点】 线型放射状粒子系统的运作。 立体感五角星的绘制。 【图例】 【代码】 <!D…

springBoot+ureport报表引擎

UReport是一款基于单元格迭代模型的纯Java中式报表引擎。它架构于Spring之上&#xff0c;因此与企业应用具有良好的集成能力。UReport提供了基于Eclipse插件与基于网页的两种报表模版设计方式&#xff0c;采用类Excel报表模版设计风格&#xff0c;简单、易上手&#xff0c;可在…

Nginx配置静态代理/静态资源映射时root与alias的区别,带前缀映射用alias

场景 Nginx搭建静态资源映射实现远程访问服务器上的图片资源&#xff1a; Nginx搭建静态资源映射实现远程访问服务器上的图片资源_nginx 当作图片资源访问 博客-CSDN博客 以上在配置静态资源映射时使用的如下配置 location / {root D:/pic_old/;try_files $uri $uri/ /ind…

游戏开发笔记:游戏海外版本时区问题(解释时区问题,分解为js写法和lua写法来分析记录,整理出对应语言的相关函数方法。)

对于海外游戏而言,与时间相关的功能,都不能忽略时区的计算。根据 ‘ 服务端资源是有限的,客户端资源是无穷无尽的 ’的定义来说,基本上时区包括时间的计算都是由客户端来进行计算,今天内容也是围绕客户端来展开。 时区算法常见的时间描述时区需要计算的点在lua语言中的写…

//简单函数_素数距离问题

任务描述 现在给出你一些数&#xff0c;要求你写出一个程序&#xff0c;输出这些整数相邻最近的素数&#xff0c;并输出其相距长度。如果左右有等距离长度素数&#xff0c;则输出左侧的值及相应距离。 如果输入的整数本身就是素数&#xff0c;则输出该素数本身&#xff0c;距离…

谷歌Google广告推广开户和投放攻略?

随着出海市场增加&#xff0c;越来越多的中国企业选择借助谷歌Google广告这一全球最大的在线广告平台&#xff0c;拓展海外市场&#xff0c;提升品牌知名度和产品销量。在这个过程中&#xff0c;选择一家专业且富有实战经验的服务商至关重要&#xff0c;而云衔科技正是这样一位…

看奈飞三体魔改 赏国产《三体》预告片AI重制版

看奈飞三体魔改 赏国产《三体》预告片AI重制版 In the vast expanse of the universe, secrets await to be uncovered. 宇宙无垠&#xff0c;秘密待揭。 A signal from the depths of space leads to an encounter with an alien civilization - the Trisolarans. 深空信号引…

nvic优先级溢出

nvic的抢占优先级大于当前的配置群组所要求的最大上限&#xff0c;则真正优先级为数值的溢出部分&#xff1b;如果溢出部分为0则循环为最大数据&#xff1a; 如上图所示&#xff1a;中断分组为2&#xff1a; 因此优先级因为0--3 TICK_INT_PRIORITY等于0xf即为15&#xff1b;与3…

何时需要指定泛型:Scala编程指南

这里写目录标题 何时需要指定泛型&#xff1a;Scala编程指南为什么使用泛型类型安全 何时需要指定泛型结论 何时需要指定泛型&#xff1a;Scala编程指南 在Scala编程中&#xff0c;泛型是一种强大的特性&#xff0c;它允许开发者编写灵活且类型安全的代码。然而&#xff0c;正…

kubectl 启用shell自动补全功能

官网手册参考&#xff1a;https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-linux/ 系统&#xff1a;centos7 补全脚本依赖于工具 bash-completion&#xff0c; 所以要先安装它&#xff08;可以用命令 type _init_completion 检查 bash-completion 是否已安装&a…

聚合支付备案新增机构名单公布,14家机构成功备案

孟凡富 3月27日&#xff0c;中国支付清算协会公布了最新一批收单外包服务机构备案机构结果&#xff0c;总备案机构为27000家&#xff0c;新增备案机构为648家&#xff0c;其中&#xff0c;新增聚合支付技术服务备案机构包括北京鑫杰华誉、深圳中峻、多点(深圳)数字科技、扬州泽…

基于MATLAB的模糊神经网络预测水质评价

%% 学习目标&#xff1a;模糊神经网络预测水质评价 %% 更多matlab精彩专题课程和案例&#xff0c;可以搜索微信公众号&#xff1a;电击小子程高兴的MATLAB小屋 %% 清空环境变量 clc clear%% 参数初始化 xite0.001; alfa0.05;%% 网络节点 I6; %输入节点数 M12; %隐含节点数…

深度学习编译工具链中的核心——图优化。

图优化 图优化的概念&#xff1a; 深度神经网络模型可以看做由多个算子连接而成的有向无环图&#xff0c;图中每个算子代表一类操作&#xff08;如乘法、卷积&#xff09;&#xff0c;连接各个算子的边表示数据流动。在部署深度神经网络的过程中&#xff0c;为了适应硬件平台…

2024年4月份 风车IM即时通讯系统APP源码 版完整苹果安卓教程

关于风车IM&#xff0c;你在互联网上能随便下载到了基本都是残缺品&#xff0c; 经过我们不懈努力最终提供性价比最高&#xff0c;最完美的版本&#xff0c; 懂货的朋友可以直接下载该版本使用&#xff0c;经过严格测试&#xff0c;该版本基本完美无缺。 下载地址&#xff1a;…

unity学习(73)——服务器异常--无法处理 123类型的数据包

服务器发送回的数据包&#xff0c;客户端根本读不出来&#xff0c;type都读不出来&#xff0c;拖了三天&#xff0c;把客户端翻了个底朝天&#xff0c;发现客户端一点问题都没有&#xff01; 所有的问题不是unity的模型问题&#xff0c;就是socket网络通信中断&#xff01; 1…

2024全国水科技大会【高峰对话】北京排水集团(附部分报告题目)

北京排水集团坚持“服务社会、造福百姓、企业利益与公众利益高度一致”的宗旨&#xff0c;充分认知自身在地区经济发展中的社会责任&#xff0c;以满足政府与公众对公用事业企业服务的需求为首要任务&#xff0c;通过“现代化的队伍、现代化的手段、现代化的设备和现代化的管理…

由浅到深认识Java语言(31):阶段性练习

该文章Github地址&#xff1a;https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

腾讯云服务器多少钱一年?最新价格整理轻量和CVM报价

2024年腾讯云4核8G服务器租用优惠价格&#xff1a;轻量应用服务器4核8G12M带宽646元15个月&#xff0c;CVM云服务器S5实例优惠价格1437.24元买一年送3个月&#xff0c;腾讯云4核8G服务器活动页面 txybk.com/go/txy 活动链接打开如下图&#xff1a; 腾讯云4核8G服务器优惠价格 轻…

leetcode热题100.寻找两个正序数组中的中位数

Problem: 4. 寻找两个正序数组的中位数 文章目录 题目思路复杂度Code 题目 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 示例 1&#xff1a; …