========================================================================================
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 书签手势实现(书签组件)
先创建这个大组件
这也是一个组件
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)”