zoukankan      html  css  js  c++  java
  • Vue-eBookReader 学习笔记(书签功能、页眉页脚、兼容性优化)

    4、书签功能、页眉页脚、兼容性优化

    4.1 书签原理

    • 功能:当用户在某一页面往下拖动时,整个页面会向下移动,并且显示上面的书签组件,移动距离达到一定阈值时书签组件就固定不动且出现添加书签字样。
    • 原理:
      • 先在阅读器组件中绑定touchmove和touchend事件,(注意为什么不是touchstart和touchend呢,因为这里要实时计算出当前移动的距离 不是仅仅需要最后和开始的距离)计算出当前离开始移动时的距离后,存到vuex中offsetY里
      • 下拉是整个页面下去,所以是index.vue整个根组件下去,是在index.vue中用watch方法监听offsetY的值有没有发生变化,如果这个值大于0就向下直接赋值为top(加上过渡动画)
      • 书签分为左右两个部分,左边是图标和文字 右边是书签的形状,这里将左边部分直接写在index.vue中,右边书签形状部分另外写一个BookMark组件(由于可能需要多次使用,写在common文件夹下)

    4.2 书签实现

    • 下拉

      • 第零阶段:当前移动量为0(touchend,手松开的一瞬间),其实就是归位操作,将当前的图标,书签形状的位置都归为最开始的样子
      • 第一阶段:绑定touchmove和touchend修改vuex的offsetY,在bookmark组件里将该值赋给样式里的top
      • 第二阶段:下拉高度在 第一阶段结束 和到阈值(添加书签)之间时,这时书签顶在上面静止不动,用书签和页面同时移动来实现(但文字和箭头还是像一开始一样)
      • 第三阶段:达到添加书签的阈值,文字和箭头都发生变化(这时书签也在上面不动)
    • 书签吸顶状态实现:当达到二三阶段时(在EbookBookMark组件内用watch监听offsetY变化),书签盒子和页面一起移动,改变样式即可(注意这里是整个书签页面都要不动,文字和形状),同时还要旋转箭头改变文字颜色什么的

    • 书签固定位置:也就是正式添加书签,这里定义了一个变量isFixed来看当前是否是书签,若是则添加相应的fixedStyle样式,若不是就删除,各个阶段根据当前是否已经存在书签(isBookmark)来判断设置isfixed为真还是假;最后到第0阶段 也就是松手的一瞬间,若isfiexed还为真就说明要添加书签,为假就不用

    • 添加书签,由于书签是要能够及时查找并且保存的,所以将bookmark数组放到localStorage中存储下来,首先通过epubjs的cfi解析原理获取 当前添加书签处那一页的文本,再将当前start的cfi和文本存入bookmark数组(首次要看是否存在,不存在则要先赋初值[])

    • 删除书签,同样也是先获取localStorage里的bookmark数组,通过比较当前页面start的cfi与bookmark数组中的cfi,若不相同则保留,相同则删除,再调用setIsBookmark(false)

    • 但像上面这样做完之后,发现添加了一页书签后每一页都会有书签显示,这时因为已经将isBookmark设为真了,而每一次翻页的时候又没有进行当前页是否是书签的判断

      • 在refreshLocation里添加当前页是否是书签页的判断(利用es6新加的数组的some方法),来设置当前的isBookmark
      • 但这样设置之后还不够,因为只是单纯的设置了,页面还没有对其做出响应,所以在EbookBookmark组件里对isBookmark进行监听,若当前是真则将书签加上,不是则不加
    • 展示书签条目:还记得之前有个component动态组件吧(用is绑定组件),切换书签和目录条目的,这里再写一个书签条目组件来切换,内容布局都很简单,和目录差不多,用scroll组件来展示,点击可以切换

    4.3 页眉页脚

    • 其实就是在页面顶部与底部放两个新的组件,这两个组件是阅读过程中一直存在的
    • EbookHeader组件的页眉,放的是当前的章节名称,比较简单,EbookFooter是页脚,放的就是当前的阅读进度,这两个组件都是绝对定位,放到index.vue里

    4.4 微信兼容

    • 手机端点击屏幕出现闪烁现象:在reset.css中加上:-webkit-tab-hightlight-color: rgba(0, 0, 0, 0);即可
    • 下拉添加书签的时候 move函数要记得加上preventDefault()
    • 在initRendition函数里,加上method: default

    4.5 PC端优化

    4.5.1 由于pc端的话必须要自适应布局才可以在不同的宽高下显示正常的比例,所以宽高定死的盒子往往就会有一些小问题

    • 在侧边栏的部分,书籍名称以及作者的地方就有些显示不完全,这就是由于宽度已经定死了,所以这里采用flex布局来让页面支持自适应,让外层盒子加上flex布局,里面文字部分是原来的ellipsis2(2),将固定的宽度去掉

    4.5.2 鼠标事件优化

    在移动端都是通过touch的事件来处理,但pc端是鼠标事件,所以这里还要再添加mouse相关的事件

    • 首先要分为四个阶段,定义一个mouseState变量,有四个值含义如下:

      • 1、鼠标进入(onMouseEnter):函数内置mouseState为1
      • 2、鼠标进入后移动(onMouseMove):移动的时候和touchmove一样的去计算当前的offsetY,一样的去改变vuex中的值去影响其余组件
      • 3、鼠标移动后松开(onMouseEnd):松开的时候和touchend一样,还原书签和文字的位置,以及设置firstOffsetY和offsetY为默认值
      • 4、鼠标松开后移动(onMaskClick):这个函数本来是处理蒙板点击事件的,所以当鼠标是按下且没有移动才会触发该事件,所以stateMouse是2或3都直接返回,不处理
    • 我们只需要处理鼠标按下后移动的状态,其余鼠标的移动不需要考虑

    • 另外需要点击消抖,有的时候鼠标按下后有轻微的移动,但是用户需要的还是点击事件,但系统判断的确是移动事件,会跳到状态3,而onMaskClick并不会对状态3的mouseState进行处理,因此这里需要增加一个对点击时间的判断,若点击时间小于某一个特定值,即使有轻微的移动,也算作是点击事件

    4.6 分页(具体到每一页)

    • 首先在EbookReader组件中的分页完毕后的回调函数里,根据观察locations分出来每一页以及navigations中目录的某部分相同,将属于同一章节的页面放到那一章节的对象下,这样就能统计出每一章有多少页,显示到侧边栏的目录条目中
    • 页脚右下角的页面要通过,改造refreshLocation函数来显示,因为每切换一次位置都要改变页码,这里是通过currentLocation.start.location获取当前页码
    • 总页数,通过EbookReader中分页完毕后将locations对象存到vuex中的pagelist变量里,后续要获取总页数就是pagelist.length即可
  • 相关阅读:
    (转载)C++ string中find() ,rfind() 等函数 用法总结及示例
    UVA 230 Borrowers (STL 行读入的处理 重载小于号)
    UVA 12100 打印队列(STL deque)
    uva 12096 The SetStack Computer(STL set的各种库函数 交集 并集 插入迭代器)
    uva 1592 Database (STL)
    HDU 1087 Super Jumping! Jumping! Jumping!
    hdu 1176 免费馅饼
    HDU 1003 Max Sum
    转战HDU
    hust 1227 Join Together
  • 原文地址:https://www.cnblogs.com/TRY0929/p/13630085.html
Copyright © 2011-2022 走看看