商业级web阅读器项目(下下)

文章详细描述了如何在EPUB电子书中实现书签功能的手势控制,包括下拉手势触发书签添加、删除以及状态管理,同时涉及页眉页脚和兼容性优化。作者通过监听offsetY值来调整页面布局和组件状态,展示了完整的交互设计和代码实现。
摘要由CSDN通过智能技术生成

this.add = !this.add

this.end = false

}

})

}, 20)

},

beforeDestroy() {

if (this.task) {

clearInterval(this.task)

}

}

}

5.阅读器–书签功能、页眉页脚及兼容性优化

========================================================================================

5-1 书签手势实现(页面下拉)

epub电子书是没有touchmove这个监听事件的,要想要这个效果,就必须添加个蒙层

在这里插入图片描述

当然要把它背景弄成透明

这样,监听事件就放在 这个蒙层上就好,通过蒙层来改变 offsetY的值,再通过offsetY的值来改变ebook的位置

蒙层上的监听事件

move(e){

let offsetY = 0;

if (this.firstOffsetY){

offsetY = e.changedTouches[0].clientY - this.firstOffsetY

this.setOffsetY(offsetY)

console.log(this.offsetY);

} else{

this.firstOffsetY = e.changedTouches[0].clientY;

}

e.preventDefault();

e.stopPropagation();

},

moveEnd(e){

this.setOffsetY(0);

this.firstOffsetY = null;

},

onMaskClick(e){

const offsetX = e.offsetX;

const width = window.innerWidth;

if (offsetX>0 && offsetX<width * 0.3){

this.prevPage();

} else if(offsetX>0&&offsetX>width*0.7){

this.nextPage();

}else {

this.toggleTitleAndMenu();

}

},

可见,已经改变了offsetY的值

接下来 index.vue中监听offsetY的改变来改变reader的top

watch:{

offsetY(v){

if(v>0){

this.move(v)

}else if(v===0){

this.restore()

}

}

},

methods:{

restore(){

this.$refs.ebook.style.top = 0+‘px’;

this.$refs.ebook.style.transition = ‘all 0.2s linear’;

setTimeout(()=>{

this.$refs.ebook.style.transition = ‘’;

},200)

},

move(v){

this.$refs.ebook.style.top = v+‘px’;

},

},

这样就实现了 下拉功能。

这里需要解释一下里面的

setTimeout(()=>{

this.$refs.ebook.style.transition = ‘’;

},200)

这是因为,那里设置的

this.$refs.ebook.style.transition = ‘all 0.2s linear’; 刚好为两秒,当松手后,动画结束,事件刚好200ms

5-2 书签手势实现(书签组件)

先创建这个大组件

在这里插入图片描述

{{text}}

在这里插入图片描述

这也是一个组件

5-3 书签手势实现(下拉状态管理)

下拉阶段分为三个阶段

第一阶段:不变。

第二阶段:在这里插入图片描述

第三阶段:在这里插入图片描述

代码实现,通过监听offsetY:

watch:{

offsetY(v){

if(v>=this.height && v<=this.threshold){

console.log(“到达第二阶段”);

this. r e f s . b o o k m a r k . s t y l e . t o p = ‘ refs.bookmark.style.top = ` refs.bookmark.style.top={-v}px` //使书签吸顶

this.text = this.$t(‘book.pulldownAddMark’); //文字改为添加书签

this.color = WHITE;

}else if(v>=this.threshold){

console.log(“到达第三阶段”);

this. r e f s . b o o k m a r k . s t y l e . t o p = ‘ refs.bookmark.style.top = ` refs.bookmark.style.top={-v}px` //使书签吸顶

this.text = this.$t(‘book.pulldownAddMark’); //文字改为释放书签

this.color = BLUE;

}

}

},

5-4 书签手势实现(书签添加删除交互)

先改变 箭头方向,在第三阶段的时候,箭头向上

在这里插入图片描述

第二阶段的时候,箭头向下

在这里插入图片描述

在上面代码中添加这个即可实现

在这里插入图片描述

添加功能完成 ,我们也应该想想一下,删除书签该怎么操作,

所以下拉的时候,要判断,是已经有了标签,还是没有,有了就是要进行的是删除操作

添加一阶段,和释放阶段

释放的时候,判断 是否 当前为书签页,是则 删除,否则添加,

watch:{

offsetY(v){

if (!this.bookAvailable || this.menuVisible){

return;

}

if(v>=this.height && v<=this.threshold){//console.log(“到达第二阶段”);

this.beforeThreshold(v);

}else if(v>=this.threshold){// console.log(“到达第三阶段”);

this.afterThreshold(v);

}else if(v>0&&v<this.height){//第一阶段

this.beforeHeight(v);

}else if (v ===0 ){//状态为0时

this.restore()

}

},

isFixed(v){

// console.log(v);

}

},

methods:{

addBookmark(){

},

removeBookmark(){

},

//下拉的第一阶段

beforeHeight(){

if (this.isBookmark){

this.text = this.$t(‘book.pulldownDeleteMark’); //文字改为释放书签

this.color = BLUE;

this.isFixed = true;

} else{

this.text = this.$t(‘book.pulldownAddMark’); //文字改为释放书签

this.color = WHITE;

this.isFixed = false;

}

},

//下拉的第二阶段

beforeThreshold(v){

const iconDown = this.$refs.iconDown;

this. r e f s . b o o k m a r k . s t y l e . t o p = ‘ refs.bookmark.style.top = ` refs.bookmark.style.top={-v}px`; //使书签吸顶

if (this.isBookmark){//当页是标签页

this.text = this.$t(‘book.pulldownDeleteMark’); //文字改为添加书签

this.color = BLUE;

} else {

this.text = this.$t(‘book.pulldownAddMark’); //文字改为添加书签

this.color = WHITE;

}

if(iconDown.style.transform === ‘rotate(180deg)’){

iconDown.style.transform = ‘’

}

this.isFixed = false;

},

//下拉的第三阶段

afterThreshold(v){

const iconDown = this.$refs.iconDown;

this. r e f s . b o o k m a r k . s t y l e . t o p = ‘ refs.bookmark.style.top = ` refs.bookmark.style.top={-v}px` //使书签吸顶

if (this.isBookmark){

this.text = this.$t(‘book.releaseDeleteMark’); //文字改为释放书签

this.color = WHITE;

this.isFixed = false;

} else{

this.text = this.$t(‘book.releaseAddMark’); //文字改为释放书签

this.color = BLUE;

this.isFixed = true;

}

if(iconDown.style.transform === ‘’){

iconDown.style.transform = ‘rotate(180deg)’

}

},

//归为

restore(){

setTimeout(()=>{

this. r e f s . b o o k m a r k . s t y l e . t o p = ‘ refs.bookmark.style.top = ` refs.bookmark.style.top={-this.height}px`;

this.$refs.bookmark.style.transform = ‘rotate(0deg)’;

},200);

if (this.isFixed){

console.log(“isFixed”);

this.setIsBookmark(true);

this.addBookmark();

}else {

this.setIsBookmark(false);

console.log(“nofixed”);

this.removeBookmark();

}

}

},

5-6 书签功能实现

添加书签

addBookmark(){

this.bookmark = getBookmark(this.fileName);

if (!this.bookmark){

this.bookmark = [];

}

const currentLocation = this.currentBook.rendition.currentLocation();

const cfibase = currentLocation.start.cfi.replace(/!.*/,‘’);

const cfistart = currentLocation.start.cfi.replace(/.*!/,‘’).replace(/)$/,‘’);

const cfiend = currentLocation.end.cfi.replace(/.*!/,‘’).replace(/)$/,‘’);

const cfirange = ${cfibase}!,${cfistart},${cfiend});

this.currentBook.getRange(cfirange).then(range => {

const text = range.toString().replace(/\s\s/g,‘’);

this.bookmark.push({

cfi:currentLocation.start.cfi,

text:text

})

saveBookmark(this.fileName,this.bookmark);

})

/**@@@ 1.console.log(currentLocation)

  • end: {index: 8, href: “A468350_1_En_5_Chapter.html”, cfi: “epubcfi (/6/18[A468350_1_En_5_Chapter]!/4/12/6[Sec3]/10[Par20]/3:426)”, displayed: {…}, location: 235, …}

  • start: {index: 8, href: “A468350_1_En_5_Chapter.html”, cfi: “epubcfi(/6/18[A468350_1_En_5_Chapter]!/4/12/6[Sec3]/8[Par19]/1:680)”, displayed: {…}, location: 234, …}

proto: Object

2.console.log(cfibase) --> epubcfi(/6/18[A468350_1_En_5_Chapter]

3.console.log(cfistart) --> /4/12/6[Sec3]/8[Par19]/1:680

4.console.log(range);Range {startContainer: text, startOffset: 680, endContainer: text, endOffset: 680,…}

5.console.log(cfiend) --> /4/12/6[Sec3]/10[Par20]/3:426

6.console.log(range.toString());//得到的是本页的内容

*/

},

删除 书签

removeBookmark(){

const currentLocation = this.currentBook.rendition.currentLocation();

const cfi = currentLocation.start.cfi;

this.bookmark = getBookmark(this.fileName);

if(this.bookmark){

saveBookmark(this.fileName,this.bookmark.filter(item=>item.cfi!==cfi));

console.log(this.bookmark);

this.setIsBookmark(false);

}

},

接下来就要把书签渲染上去呢,过程和 目录一样

这是复制搜索列表的,稍微做了点修改

<scroll class=“slide-search-list”

:top=“66”

:bottom=“48”

@click=“displaySearch(item.cfi)”

5-7 页眉和页脚功能实现

在这里插入图片描述

两个组件

{{getSectionName}}

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值