- 同屏滚动
一个界面左右两边是两篇文章,想实现右边文章滚动时,左边文章也跟着滚动,左边滚动时右边不动。
pdfjs导航栏的样式已修改过
pdfjs界面渲染完成之后,写一个定时器监听滚动条移动
this.interval = setInterval(this.checkPdf, 300);
let pdfFrame = document.getElementById("tranIframe").contentWindow; //左
let pdfFrameTran = document.getElementById("orgIframe").contentWindow; //右
if (!pdfFrame.document.getElementById("pageNumber")) {
return;
}
let maxNum = pdfFrame.document
.getElementById("pageNumber")
.getAttribute("max");
if (maxNum == 0 || maxNum == undefined) {
// 直接获取页面显示的总页数,获取到了说明加载完成
console.info("Loading...");
} else {
this.pdfLoading = false;
if (maxNum < 2) {
// 只有一页的pdf,进度更新为100%
console.log(`1/1, prog:100%`);
} else {
if (!pdfFrame.document.getElementById("viewerContainer")) {
return;
}
pdfFrame.document
.getElementById("viewerContainer") // 监听pdf滚动事件(这个id是pdfjs自带的)
.addEventListener("scroll", (e) => {
let pdfInfo = pdfFrame.PDFViewerApplication;
// pdfPageNow: pdf当前页码
if (this.pdfPageNow !== pdfInfo.page) {
// 防抖:当前页变化时,更新进度
this.pdfPageNow = pdfInfo.page;
pdfFrameTran.PDFViewerApplication.page = this.pdfPageNow; // pdf跳页
console.log(`${pdfInfo.page}/${pdfInfo.pagesCount}`);
}
});
}
}
},
当前实现方法的逻辑是 监听页码变化,右边页码改变,左边也改变,这样做有一个问题就是,当页面高度小,要稍微滚动一下滚动条才能展示完一页的内容,就会出现右边往下滚动,左边就马上跳转到下一页,视觉效果有点像卡顿。
优化其实很简单,上面代码的最后改成以下代码,通过js 的scrollTop 方法实现同屏滚动
pdfFrame.document.getElementById("viewerContainer") // 监听pdf滚动事件
.addEventListener("scroll", (e) => {
pdfFrameTran.document.getElementById("viewerContainer").scrollTop =
pdfFrame.document.getElementById("viewerContainer").scrollTop;
})
这个优化在不同场景下还是有个问题,例如左边是中文,右边是翻译后的英文,由于中英文的字节长度问题,左右两边的总页数可能不一样,同屏滚动时就会出现错位(即左边的原文不能准确对照到右边的译文)
解决此问题,参考了有道翻译的同屏滚动,当左右两边内容相差过大时,用户可滑动左边进行微调来手动对齐,这样再滑动右边时就不能用scrollTop直接赋值了,需要计算出右边滚动条当前移动的距离,再进行赋值
data() {
return {
scrollT: 0
}
}
pdfFrame.document.getElementById("viewerContainer") // 监听pdf滚动事件
.addEventListener("scroll", (e) => {
let scrollT = pdfFrame.document.getElementById("viewerContainer").scrollTop;
let roll = scrollT - this.scrollT;
this.scrollT = scrollT;
pdfFrameTran.document.getElementById("viewerContainer").scrollTop =
pdfFrameTran.document.getElementById("viewerContainer").scrollTop + roll;
})
- pdfjs使用
方法
写到这了顺便写一下pdfjs使用
- 下载pdfjs地址:http://mozilla.github.io/pdf.js/getting_started/
- 把下载好的文件全部放到vue里面
这里有个问题,就是文件位置
因为引用的时候找不到src下面的路径,所以只能放在public里面,这样在打包的时候就会暴露出来,我暂时没有其他的办法,若有其他办法,希望不吝赐教。
<iframe
v-if="!contrast"
:src="`/pdfjs/web/viewer.html?file=${encodeURIComponent(href)}`"
id="orgIframe"
width="100%"
:allowTransparency="true"
frameborder="0"
style="height: calc(100% - 4px)"
>
</iframe>
- pdfjs的使用e就是在src前面加路径,by the way,想改样式跟事件,是在/pdfjs/web/viewer.html和/pdfjs/web/viewer.js里面改,样式都在/pdfjs/web/viewer.css里面
- href是文件流,调接口获取及下载文件流看我另一篇文章
参考文章:https://betheme.net/xiaochengxu/82731.html?action=onClick