三、阅读器开发--2.标题菜单、字号及主题设置

#在vue lic3.0后创建的项目中,它会自动去帮我们安装git,进行git的初始化

1、阅读器解析和渲染

1.1配置ebook入口文件

我们把Home、About这些删掉,views下建个名为ebook的文件夹,该文件夹下建个index.js作为阅读器的入口文件,再去配置router.js:入口文件嘛,所以path2为/使就让它重定向到/ebook,路径为/ebook是就异步加载index.vue组件的页面,通过()=>import('路径')这就是动态引入,就是懒加载,就是一种按需加载,就你要看这个页面我再给你加载这样子,就提高性能嘛

1.2实现动态路由

我们想要实现如localhost:8081/#/ebook/History|2017_Book_InterdisciplinaryPerspective这种ebook后面跟了一串字符串,字符串前半部分是分类名称History然后一个竖线再后面是一个电子书名称这种格式,也就是动态路由的方式去获取一本电子书,如果我们将History或将后面的电子书名称改变那么获取的电子书也会更换,我们可以通过这种方式来寻找我们nginx服务器上的电子书。

要实现动态路由,第一步需要有动态路由的组件,我们在components下建一个ebook文件夹,ebook文件下建一个EbookReater.vue,用来接收我们的动态路由。然后我们要到router.js中加上这个组件,以children接在path为/ebook后面,如下:

//注意children它是一个数组,数组里面的内容就是动态路由,动态路由是以冒号作为起点,冒号后面是接收的参数名称即fileName,fileName就会传入History|2017_Book_InterdisciplinaryPerspective这样的内容进来

然后还需要在其父组件也就是ebook的index.vue当中引入这个子组件

引入:import EbookReader from '../../components/ebook/EbookReader';注册components:{EbookReader} ;使用<ebook-reader></ebook-reader>

然后我们到EbookReader当中,建一个class用来接收这个参数

如下图所示,我们url中ebook后面的fileName就接收到啦,说明动态路由生效了,也就是当前页面会根据我动态路由的内容而展示不同的内容

1.2.3接下来去拼接出一个路由,这个路由可以访问到nginx服务器,并且根据你拼接的这个路由里面的电子书从而把电子书下载出来。

就你访问这个路由你就可以下载到nginx里面相对应的电子书,我们需要下载这个电子书然后放到我们的阅读器中。

你怎么知道你要搞出一个什么样的路由才能下载到nginx服务器中的电子书呢?

如下nginx服务器我们是直接点击里面的epub里面的某一本书,一点击它就下载到我们的电脑中啦,所以我们仿造它这个路径去访问localhost:8081/epub/History/2017_Book_InterdisciplinaryPerspectivesO.epub,可以发现和访问nginx服务器到epub中点击某本书从而下载出来是一样的。

接下来我们就可以根据动态路由来展示电子书,将动态路由挂载到id为read的DOM下,然后在这个EbookReader的div中就放这个id为read的DOM,也就是说电子书放在这里,跟上面同理,你放不同的电子书那当前页面就展示不同的电子书

即可实现如下访问这本电子书时fileName就保存下了

下面我们就来解析这个路由,我们需要将它拼接成nginx目录,这里我们用正则表达式,如下我们用split('|')把它们分开,然后再用join('/')来将它们拼接在一起

我们要做的是去访问nginx服务器里面的内容,就需要一个访问nginx服务器里面文件的路径,上面是电子书的路径已经拼接好了,再往前是nginx服务器的路径,如下,这两个拼接到一起就是我们要的访问nginx服务器中这本书的路径。最终我们就会得到控制台输出的那种路径

如上还不行,因为nginx的epub文件夹下的电子书文件后面都是.epub结尾的,所以应该加上.epub

最终你访问如下路径时就会打印出下面第一个图打印出的路径http://192.168.112.42:8080/#/ebook/History|2017_Book_InterdisciplinaryPerspectivesO

你一点击控制台的那个路径,就会跳到nginx那边把这边电子书下载到你电脑上

1.2.4接下来引入epubjs

1.2.4.1使用vuex

由于这个fileName经常用,所以我们把它放到vuex中。大致如下

首先把fileName放到state中,mutations中定义一个方法去修改state中的fileName值,actions去定义一个方法去调用mutations中方法。

然后在getters.js中设置fileName,哪里用fileName哪里就引入引入mapGetters、...mapGetters,然后如下,如果我们没有getters,那么我们获取state中的fileName是通过this.state.book.fileName才能获取,但是因为有了getters,getters中我们已经把state.book.fileName变成了fileName,所以只需要访问this.fileName即可获取到state中的fileName

最后哪里要修改fileName的值,就在哪里通过this.$store.dispatch去调用actions中的setFileName方法去调用mutations中的方法去修改state中的fileName值

最终initEpub中就用vuex中的fileName获取到了该电子书的下载路径,如下

渲染电子书的时候,电子书渲染不出来报错如下问题

这个报错我暂时搞不出来,怪我太菜,为了先往后做,我就先用一个固定的电子书路径做,后续再来解决这个问题了。

2、阅读器翻页手势操作功能实现

之前是通过蒙版分left、center、right三个区域,点击left即翻上一页,点击right即翻下一页。

这次就实现用移动端的手势来实现翻页,即从左往右滑动就会返回上一页,从右往左滑动就会返回下一页,滑动的位置是不限制的,可以在任意位置进行滑动翻页,点击屏幕就会出现标题和菜单,同样点击的位置也不受限制,我们翻页的时候如果标题菜单在就会先隐藏标题菜单再翻页。

电子书epub对象实现原理是使用iframe,那么我们如何向iframe里面绑定事件呢?epubjs为我们提供了一个on方法,即通过this.rendition.on('',)将事件绑定到iframe上,如下

我们主要是通过event下面的changedTouches下面的clientX是指当前点击的位置,主要通过它来判断

同时我们对手势操作的时间也有要求,如果操作时间过长我们就不确认这次操作,如下可以通过event里面的这个timeStamp规定,我们自己规定它不能超过500毫秒

下面代码实现

然后在计算好偏移量和时间后实现我们的手势,如下

这个禁止事件默认方法调用event.preventDefault();  和 阻止事件冒泡event.stopPropagation(); 在事件处理程序中调用它们是非常常见的需求。阻止默认事件:某些标签带有默认的事件,例如a标签默认跳转页面,submit属性默认提交并刷新页面,如果不需要触发这些默认的事件,就需要阻止默认事件了。阻止事件冒泡:如果不需要让事件向上传播就需要阻止事件冒泡了

 3、标题栏和菜单栏实现

3.1标题栏

components下的ebook文件夹下创建标题栏组件和菜单栏组件,即EbookTitle.vue和EbookMenu.vue,并且在ebook的入口文件即views下的ebook的index.vue中引入这两个组件

之前的时候做过这两个,所以直接拷贝源码过来即可

然后上面的@include center是在global.css中做的,现在我们如下

如下,即可完成标题栏,然后调整一下图标大小和标题栏显示问题即可

标题栏显示问题

我们之前是阅读器与标题菜单栏是父子关系,但是我们现在是平行的即兄弟的关系,我们是希望点击阅读器那么标题菜单栏就进行显示或隐藏,那么这之间的值该怎么传递呢,已经不再是之前的父子组件之间的传递方式了。

我们需要借助vuex来传值,这个值我们定义为menuVisible。

首先我们先到modules下的book.js中定义menuVisible,然后到getter中定义

然后在标题组件中把getter直接引入进来,然后就可以直接用menuVisible了

此时点击发现标题栏没出现,因为你menuVisible默认是false呀,是true的时候才显现,也就是说你点击屏幕事件中应该去改变state中这个menuVisible的值。所以到阅读器组件中点击事件加入如下,并且注意...mapGetters([])中记得要加入menuVisible才行

点击标题栏出现,再次点击标题栏隐藏实现了,但是过渡动画没有实现,接下来实现,我们把之前的过渡动画都拷贝过来,然后放在一个新建的transition.scss中,然后在global.scss中引入这个transition.scss中即可,然后过渡动画就可以实现了

3.2菜单栏

同理拷贝代码到菜单栏中,然后到ebook下的入口文件index.vue中引入这个菜单栏,之前我们已经引入了

然后标题菜单显示的时候翻页,我们想要翻页前标题菜单自动隐藏起来再翻页。我们之前的toggleTitleAndMenu方法是显示时就隐藏、隐藏时就显示。我们翻页的时候去调动这个方法的话,即如下,就会翻页过去标题菜单栏会隐藏起来了,再翻页的时候它到下一页标题栏就又出来了,因为false、true状态一直在切换嘛

而我们想要的是翻页的时候它一直为false隐藏起来,所以应该重新定义一个函数hideTitleAndMenu,如下

3.3mixin机制

这里我们发现有很多重复性的代码,如引入mapGetters,...mapGetters()这些等,我们想把这些重复的代码抽象到一个固定的地方去维护,可以通过vue的mixin机制解决这个问题

具体怎么做:首先在src下面创建一个目录叫utils,其下建一个文件叫mixin.js,在mixin当中我们指定ebookMixin这样的一个对象,这个对象当中我们可以将重复的代码放到这里来,我们把mapGetters引入进来,然后把...mapGetters引入进来,如下然后让所有的组件都引用这个mixin,以后我们修改只需要在这一处进行修改即可,从而实现我们代码的复用。所以其他地方我们可以把这些重复的代码去掉,然后如下引入mixin,通过vue中mixin这样的标签把我们混入的内容放进来,那么vue在实例化过程中就会将ebookMixin里面的内容与我们当前EbookReader当中的内容进行混合,从而实现mixin的复用

后面我们的EbookTitle等组件都可以这样做。当然复用内容即ebookMixin中的内容不止可以是计算属性computed也可以是方法也可以是一些变量等都是可以用来复用的。通过vuex和mixin我们就可以实现组件间的解耦和复用。

接下来再讲一下,我们之前使用vuex中actions中的方法时都是使用this.$store.dispatch('setMenuVisible',false)方法,还有一种更优雅的方法直接通过this.setMenuVisible(false)来实现调用actions中的方法,和getters相类似,vuex就为我们提供了这种机制mapActions。怎么实现:先引入mapActions,然后mapGetters与mapActions的区别是...mapGetters是混入到计算属性computed当中,而...mapActions是混入到methods=当中,如下

所以引入mixin的地方使用actions中的方法时就不再需要通过this.$store.dispatch('actions中的方法',传的值)了而是直接this.actions中的方法(传的值),如下

4、菜单栏字号设置面板

把之前的html和css样式拷贝过来

首先设置面板的显示与否是通过菜单栏的来决定是否显示,点击了菜单栏中的图标就显示,也就是这里我们需要通过vuex来进行值的传递(vuex在store下modeules下的book.js中),在book.js、getters.js、mixin.js下如下

然后字号显示面板中引入mixin

设置面板要显示要2个条件,第一个菜单栏要显示第二控制面板显示,所以控制菜单栏的menuVisible要为true同时控制设置面板的settingVisible要显示

然后我们去设置菜单栏中设置面板中展示字号、主题、进度条、目录其中哪一个的方法。

咋实现呢,我们之前在vuex中设置了面板如果为-1就不显示、为0则显示字号、为1则显示主题、为2则显示进度条、为3则显示目录,然后如果settingVisible为0-3就显示嘛,那默认为-1即默认面板不显示,那你改变settingVisible的值即可实现显示哪种面板了嘛,所以方法就是去改变vuex中的值即可,如下

我们再来搞这个fontsizeList以及setFontsize以及defaultSize(这个在vuex,mixin中引入即可)

我们可以直接放在这个组件data下面,我们也可以考虑在utils下创建个book.js,将所有静态的变量都放到这里进行统一管理如下图2这样更便于管理

哪里需要用就哪里直接引入即可,如下

此时若设置栏显示状态,然后我们点击屏幕,菜单栏标题栏设置栏一起回去了,但是再点击它们出来的时候设置栏是显示状态就有点奇怪,我们希望点击显示菜单栏时设置栏是隐藏状态,点击菜单栏图标它再显示,所以我们再hideTitleMenu中设置this.setSettingVisible为-1即隐藏状态

此时点击字号切换是无效的,接下来我们来实现字号切换功能。

通过this.book.rendition.themes.fontSize()可以实现字体大小切换功能,往括号里传你点击的大小即可。但是现在这里.book是没有办法获取到电子书的,因为当前这个this.book对象还没有写入到vuex当中,此时book对象只是在EbookReader中new出来,所以我们可以到EbookReader把new出来的book对象放到vuex当中,这样任何组件就都可以使用这个book对象啦,同理加到modules中的book.js中,以及geeters以及mixin中

在EbookReader中获取到电子书的book对象后就修改vuex中的book对象,然后其他组件就可以通过this.currentBook来用这个book对象了

然后字号设置栏就可以使用这个this.currentBook.rendition.themes.fontSize()去修改电子书的字体大小了,而且注意要加上单位,还要注意defaultFontSize默认字号也设置上哦

接下来我们做字号的离线缓存功能,缓存字号到浏览器中

我们设置好字号后,一旦刷新页面,所有配置都会回到默认配置,这是因为这些配置都没有进行缓存,这里我们使用localStorage来存储这些数据,我们在浏览器中打开Application即应用可以看到Storage。这是html5加入的,是为了解决cookie存储空间不足的问题,cookie每一条存储空间只有4K,而localStorage一般为5兆。

下面我们就将localStorage来引入我们的项目,先停止项目,安装一个localStorage库 : npm i --save web-storage-cache

安装完后我们在utils下面创建一个localStorage.js,把这个库即web-storage-cache传入,这个库好处是能把我们传入的字符串,比如我们传入的是一个对象它可以变为JSON再存储,然后我们读取的时候它可以将JSON字符串再转化为对象,使用起来就很方便。

然后我们要创建一个localStorage的变量,通过new Storage()。往localStorage写入东西用localStorage.set(key,value)即可,从localStorage中取出东西用localStorage.get(key)即可,删除localStorage中的值可以通过localStorage.delete(key),全部清空可以通过localStorage.clear()

因为我们每一本电子书它所存储的内容可能都不一样,所以我们为每一本电子书都开一个localStorage空间,所以我们定义一个setBookObject,我们将localSotrage的key定义为fileName即电子书路径,这个fileName下面又包含了一个key value。

定义一个book对象  通过getLocalStorage去取一下,看看通过这个fileName能不能取的到,如果能取的到,能够取到就把book的key、value赋值进去;不能取到就先把book定义为一个对象,然后再进行key、value赋值;写入完成之后保存到localStorage中。然后我们再写一个获取的代码,这样我们就封装完了一个最基础的源码

在此基础上,比如说我们想要存储获取我们的字号该怎么做呢,可以如下

方法封装完成,我们到具体的应用场景中应用,如下我们做字号的缓存

如下,切换字号的方法中保存字号到本地缓存中。然后浏览器中本地存储就能保存到了。

但是这里有一个问题,就是我们刷新页面后可以看到默认的时候是没有字号的,也就是字号没有初始化过程,下面我们做一下初始化的过程,在display()之后做初始化,

5、阅读器主题设置功能实现

我们之前只是实现阅读器的主题切换,现在我们来实现整体的全局的主题切换

内层阅读器由于它嵌套在iframe里面,它的样式切换我们仍然需要通过themes对象来实现,而外层主题样式的切换需要通过动态加载css来实现。

我们先实现阅读器主题设置,我们之前有设置过,下面我们就来做代码集成

如上图可知我们还需要一个主题数组,然后一个改变主题的方法,接下来我们就做,主题数组是一个静态数据所以我们在utils的book.js中写(这个book.js我们就是专门用来放静态资源的)

写好themeList后,在要用到themeList的组件中引入utils/book下的themeList后去使用这个themeList

我们发现好几个地方可能要用到这个themeList,所以我们把它引入到mixin当中

然后我们去搞defaultTheme,同理在vuex、actions.js、getters.js、mixin.js中定义好这个默认主题

然后到EbookMenu中把这个EbookSettingTheme组件引入进来

然后选中的主题我们是让它有绑定class即特殊有selected样式的,可是这里没有显示出来,这是因为我们defaultTheme默认的时候是通过name来匹配的,而原先这个是用index匹配,所以我们要改一下把index改为name即可

接下来写切换主题的方法,同理调用book对象的theme对象实现主题切换,只不过主题这里要注意用户点击主题我们获取到的是index,而不是直接获取到主题所以需要先转换一下,而且我们主题是以theme中的name为辨识的而不是theme为辨识,所以像改变默认主题这些是传入theme的name值而不是theme值。

首先我们先注册主题以及select渲染主题

这是初始化电子书的时候应该做的所以在EbookReader中做注册主题以及select主题,这只是电子书初始化时注册select主题

然后接下来我们来实现设置主题功能

主题切换就是获取到当前点击的主题名称后去改变vuex中的默认主题,然后再通过book的thmes去调用select方法去切换主题即可

同样我们将主题进行缓存,在ebookReader当中增加缓存功能,

接下来我们做动态加载css去切换全局样式

动态切换全局样式的原理是为DOM动态添加或删除CSS文件,我们知道css的引入是通过head标签下添加link标签,那么动态添加或删除css文件的原理也是一样的,就扫它的head标签,往head中添加我们自定义的link标签即可。

到utils中的book.js中添加一个方法,即动态添加css

去初始化全局样式。

nginx中有这四个主题样式的css文件了,我们通过如下可以打开nginx中的这个css文件

把这个路径拷贝下来放到如下,可以看到标题栏菜单栏设置栏就都是这种颜色的css样式啦

接下来我们需要根据当前默认的主题来动态的切换,怎么实现呢,通过switch case,如果当前默认主题为Default则加载xxx的css样式文件,然后如果当前默认主题为xxx则加载xxx的

此时去切换主题,发现标题菜单栏没有跟着切换,去看看head最后,点击切换主题,head后面没有动态添加link,也就是上面的addCss没有成功

因为这个initGlobalStyle是在EbookReader中,而切换主题时在主题设置栏中,还没有把initGlobalStyle传过去,所以你主题设置栏中点击跟这个EbookReader中的这个方法没有关系。也就是在主题设置栏中的切换主题的setTheme方法中需要添加一个设置全局样式的方法。我们把initGlobalStyle放到mixin中进行复用,然后​​​​​​​主题设hi在栏中调用该方法即可实现全局样式切换啦

这里还要解决一个问题,就是我们每点击一次就会在最后添加一个css的link文件,当用户反复点击后那么就会添加很多样式文件,后一个会覆盖前一个,这样会降低我们的渲染效率,下面我们就来做一个清除样式的css方法来解决这个问题

然后在设置全局样式前先移除所有的动态css样式文件即那link

此时切换主题,到head标签看,可以看到之前的主题link会被清空,全局只会保留一个css样式

### 回答1: times-new-roman.ttf是一种字体文件。它是由著名字体设计师斯坦利·莫里森(Stanley Morison)在20世纪初设计的。times-new-roman.ttf是Times Roman字体家族的一种成员,也是最常用的成员之一。 times-new-roman.ttf具有许多优点,使它成为众多文档和印刷品中的首选字体之一。首先,它的字形清晰、优雅,使得文本易于阅读,特别是在小字号、大段落和复杂排版的情况下。其次,times-new-roman.ttf的字符之间的空间分布均匀,使得整个文本在排版时显得舒适和稳定。此外,times-new-roman.ttf的线条细节和字母形状的一致性,使得它可以适应不同的打印和屏幕显示设备,确保文字表现力的一致性。 times-new-roman.ttf在许多场合中都被广泛应用。首先,在印刷行业中,它是报纸、杂志和书籍中广泛使用的标准字体。其次,在办公场所和学术机构,times-new-roman.ttf被广泛应用于文件、报告、论文和演示文稿中,因为它传达出专业、正式和可读的外观。此外,在电子文档中,times-new-roman.ttf能够呈现出良好的可读性,不仅在电脑和平板设备上,也在小屏幕手机上。 总之,times-new-roman.ttf是一种经典、高影响力的字体文件,以其独特的风格和广泛适用性受到广大设计师、排版员和写作者的喜爱。无论是印刷品还是电子文档,使用times-new-roman.ttf都能够提供清晰、优雅且一致的阅读体验。 ### 回答2: times-new-roman.ttf,是一种常见的字体文件格式。它是以Times New Roman字体命名的TrueType字体文件。Times New Roman是一种常见的无衬线字体,由Stanley Morison在1931年设计。这种字体在英文出版物中使用广泛,尤其是在报纸和杂志上。 times-new-roman.ttf文件常用于电脑操作系统、字处理软件和排版软件中,用于显示和打印Times New Roman字体。它可以在Windows、Mac和Linux系统上使用,并且可以在各种应用程序中使用,如Microsoft Word、Adobe Photoshop和Adobe Illustrator等。 使用times-new-roman.ttf文件,用户可以在其计算机或设备上安装Times New Roman字体,并将其用于各种文档和设计项目中。由于Times New Roman是一种风格简洁、易读且经典的字体,因此它在商业文档、学术论文、广告设计等方面都非常常见。 此外,times-new-roman.ttf文件还可以用于网页设计和开发中。通过将times-new-roman.ttf文件与CSS(层叠样式表)配合使用,开发者可以在网页中使用Times New Roman字体,并确保在不同的操作系统和浏览器上一致地显示。 总而言之,times-new-roman.ttf是一种常见的TrueType字体文件,用于在计算机系统和各种应用程序中显示和打印Times New Roman字体。它在印刷和数字媒体中都有广泛的应用,是一种风格简洁、易读且经典的字体。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值