最近在帮同事在旧系统增加功能时又接触到viewer.js,其中踩了些坑,直到跟踪到源码才找到解决方法。
旧系统是N年前的系统,采用jquery+自研发的UI进行的开发,其中引入了一些插件,其中图片预览就是采用的viewer.js。之前上传的文件只有图片,所以预览并没什么问题,新需求中要求可以上传PDF文件,上传后点击pdf图片在新页面打开pdf文件。
思路
上传文件成功胡判断文件后缀,普通图片就在dom中添加一个img标签并设置src和data-org属性为图片地址,pdf文件添加个img标签设置data-org属性为图片地址src为一张pdf图片。通过事件委托实现点击pdf图片时获取data-org属性并进行跳转。
问题
按思路开发完成后发现pdf图片还可以预览,这个并不是想要的效果。那就需要想办法预览时去除部分图片。
解决思路
系统中使用的viewer是jquery的插件,但是当前已经停止维护了,地址是https://github.com/fengyuanchen/viewer 版本是0.5.1
方案1. 首先要去官网查看有没有想过API,于是在找到github找到了filter方法,看这描述妥妥得能解决了:
这样只要给pdf图片添加个特定的class,判断只要有此class就返回false。一番操作后发现没有生效,排查发现是系统中引用的viewer.js版本较低并没有filter方法。贸然升级风险较高,只能再看看当前使用的版本是否有其他API。
方案2. 百度搜索相关方案(大部分都是复制粘贴的),没啥借鉴意义,倒是根据名猜到可能有用的属性:show
show是预览前的钩子函数,返回true能进行预览,返回false是不能进行预览。这样只要参数中能区分就能实现,遗憾的是并不能区分。
方案3. 既然show钩子函数中不能区分那只能自己设置个flag了。全局设置flag为true,在pdf图片上绑定click事件,除了在新页面打开pdf外还要设置flag为false。这样在show函数里根据flag的true/false判断要不要显示。但是虽然点击pdf图片不会弹出预览但是在底部缩略图还是有pdf图片的,又放弃了这种方案。
方案4. 只有在底部缩略图中看不到图片才是真理,不能把视线放在图片的点击事件上。既然这样,为何不看下底部缩略图的dom,只要在底部dom中图片未出现也肯定不会加上图片预览效果。
查看官方demo中所有缩略图都放在.viewer-list元素了,那不妨先看下哪些图片才会放到这个元素中。
从这里可以看得出$list正是缩略图的容器,在初始化的时候通过遍历this.$images
把缩略图插入到容器中。所以只要找到this.$images
的规则就能设置部分图片不预览。
这里能看出当前元素如果是img就取当前元素,否则取当前元素下所有img元素。所以,但凡是img标签的都会添加预览效果,那有没有不用img标签而显示图片呢,没错,就是背景图片。
解决方案:把不想进行预览的图片通过背景图片的方式展示出来。
以上只针对https://github.com/fengyuanchen/viewer/releases/tag/v0.5.1
viewer.js 1.7.2实现方式如下
可以看到如果设置了filter方法就会筛选出filter返回true的图片进行预览。当然也是筛选的img标签。所以通过设置背景图片的方法还是适用的。