试用Foxit PDF: 在网页中单页展示PDF

产品需求

在网页中展示PDF文件,每次展示一页,通过按钮进行翻页。

思路分析

之前网站功能分别使用vue-pdf和pdfjs-dist实现过,但渲染速度都特别慢,所以想试试foxit pdf插件。网站只是用插件单页展示PDF文件,功能简单,在官网提供的插件包里也有只渲染单页的示例代码,稍加改动后即可使用,但实施过程中发现有许多坑,于是想找官方文档,费了好一番功夫才找到一个中文文档,但发现里面也没有详细的参数配置说明,所以只能自行摸索。

过程经历

问题1

根据项目需求,让PDF的宽度撑满父盒子是比较理想的,而在PDFViewer的配置项中有一个defaultScale字段,是与PDF的显示尺寸相关的。defaultScale的取值为数字或字符串,因为没有明确的官方说明,所以只能试,已知的可取值为:fitWidth(默认值)、fitHeight、数字(缩放比例)。

其中fitWidth比较符合需求,但实际操作时,当取值fitWidth(fitHeight也是)时,页面总是会出现滚动条。

从控制台可看到html上有一个"--facing-margin: 8px;",如果在控制台将该样式去除(或将主dom元素display设为block)则滚动条会符合预期,于是做了如下尝试:

1)新增CSS样式,将--facing-margin覆盖为0px,发现问题依旧;

2)直接在库代码中(js文件和css文件中各一处)将--facing-margin值改为0px,发现问题依旧;

3)将主dom元素display设为block,问题依旧;

4)将比例调小(比如将defaultScale设为0.95),可解决问题,但取值不好控制;

5)在上面的测试过程中,发现将--facing-margin改为0px后,再触发滚动事件后,可以触发页面重新计算,这时滚动条会变得符合预期。所以在PDF文件加载完成后用代码触发滚动事件,问题解决。

问题2

当将调整后的Demo代码移植到实际项目以后,PDF计算后的尺寸并非是父盒子的宽度,而是网页视窗窗口的宽度。又因为PDF的父盒子大小与视窗大小没有固定的比例关系,所以考虑将PDF的显示放在一个单独页面中,再用iframe嵌入网页中进行使用。

不过,这样做的话,iframe的高度不会根据内容去自动调整,所以只能人为调整。此处使用的方案是:iframe打开PDF文件后,通过postMessage将PDF的尺寸信息和页码总数发给外层窗口,外层收到尺寸信息后再修改iframe的高度。

问题3

将iframe嵌入网页后,当PDF翻页时,发现iframe时而有滚动条时而没有,时而PDF是撑满网页的,时而又与边框存在间隙。

在控制台可以看到PDF的尺寸闪烁是因为每次翻页时都会重新计算宽度,而当某次因为某些原因产生滚动条后,滚动条会压缩网页的有效宽度,那么下次翻页时计算的宽度就会偏小,于是又会出现间隙(如图所示,间隙大约8px,默认的滚动条宽16px,所以大体可以猜到原因)。

解决办法是直接在iframe网页中将html的overflow直接设为hidden,这样就可以避开滚动条对尺寸计算产生的影响。那这样改了以后会不会影响上一步postMessage中的PDF高度尺寸呢?实测的结果是不会。如下图所示,overflow:hidden不会影响scrollHeight等信息(图片中的渲染效果是在控制台人为修改的,非浏览器自动渲染,正常的页面高度不会缺损)。

最终结果

初始化时,因为要下载PDF文件,速度慢些;之后的操作还是比较流畅的,效果还可以。

相关推荐
大G哥5 分钟前
我用豆包MarsCode IDE 做了一个 CSS 权重小组件
前端·css
乐闻x10 分钟前
Vue实践篇:如何在 Vue 项目中检测元素是否展示
前端·javascript·vue.js
麻花201325 分钟前
WPF里面的C1FlexGrid表格控件添加RadioButton单选
java·服务器·前端
理想不理想v39 分钟前
【经典】webpack和vite的区别?
java·前端·javascript·vue.js·面试
羊子雄起1 小时前
CKEditor前端样式和编辑器的样式不一致的问题
前端·编辑器
聊无生1 小时前
JavaSrcipt 函数高级
开发语言·前端·javascript
xiyusec1 小时前
HTML基础
前端·html
好开心332 小时前
javaScript交互案例2
开发语言·前端·javascript·html·ecmascript·交互
xChive2 小时前
优化表单交互:在 el-select 组件中嵌入表格显示选项
前端·vue.js·交互·element-plus
tian-ming2 小时前
(十八)JavaWeb后端开发案例——会话/yml/过滤器/拦截器
java·开发语言·前端