我们公司之前的需要实现的功能  pdf上传、定位、浏览功能,这块主要我负责,就像上一个博客写的一样,遇到很多很多的问题,主要用到的js就是pdf.js,实现对上传pdf的浏览,上一个博客记录的是跨域问题(跨域问题是很重要的一个,因为一般文件服务器和项目服务器是分开的),下面记录一下如果实现的行定位功能。

本来我是不打算用行定位的,因为之前考虑了一下是完全没有头绪的,因为pdf.js主要就是点击缩略图定位到对应的页码实现页码跳转的。因为用户点击不可能点击的是pdf.js内部的按钮,需要在外部添加按钮(相当于锚点功能)。主要功能点:锚点设置 和 锚点定位。

下面我就只讲行定位的方法:

思路:pdf.js有个目录功能,点击目录中的标题就实现了行定位,我就是受这个启发才去思考的实现行定位。首页通过页面F12去查看目录定位的连接,发现是一串编码(不知道啥格式),我就复制出来去网页中转码过来,发现格式如下:

#[{"num":23,"gen":0},{"name":"XYZ"},74,769,0]
#[{"num":46,"gen":0},{"name":"XYZ"},74,442,0]

这是其中二个标题对应的编码转换后的代码,我当时发现就二个地方是不同的,一个就是 num的值,另一个就是后面倒数第二个的数字,接下来就要去找源码了,一个一个的console,终于在viewer.js的9285行找到了端倪(由于每个版本的行数不一样,下面是我复制的那个js方法,因为加密电脑不能截图,只能给代码了):

key: '_updateLocation',
value: function _updateLocation(firstPage) {var currentScale = this._currentScale;var currentScaleValue = this._currentScaleValue;var normalizedScaleValue = parseFloat(currentScaleValue)...........

这个方法console方法当你滚动页面的时候就会走这个方法,这个方法中的后面有几个非常重要的参数

 this._location = {pageNumber: pageNumber,scale: normalizedScaleValue,top: intTop,left: intLeft,rotation: this._pagesRotation,pdfOpenParams: pdfOpenParams
};

通过打印能够发现其中的pageNumber就是当前页码,intTop 就是发现那个编码中的变化数字中的倒数第二个参数,解释为高度(哈哈,现在才知道不是记录的行,而是记录的当前页码的高度实现的“行定位”),现在第一个参数有了,主要目标就是那个num的值了,跟我们在页面看到的值完全不一样的,我就猜想一定是一个json或者数组啥的通过key value对应到的页码,然后我就通过这个方法顺藤摸瓜,找到了大本营:

{key: 'cachePageRef',value: function cachePageRef(pageNum, pageRef) {if (!pageRef) {return;}var refStr = pageRef.num + ' ' + pageRef.gen + ' R';this._pagesRefCache[refStr] = pageNum;}}, {key: '_cachedPageNumber',value: function _cachedPageNumber(pageRef) {var refStr = pageRef.num + ' ' + pageRef.gen + ' R';return this._pagesRefCache && this._pagesRefCache[refStr] || null;
}},

我这边大概在7139行(viewer.js),这二个方法狠狠重要,一个是页码(下面),一个是创建的key-value格式的编码(上面一个),通过console得知,当你加载pdf文件的时候就会去调用上面这个方法,将页码和编码对应(对应格式是“27 0 R”-“4”,4是value就是页码,前面是key就是编码)。

到目前为止获取就有了(拨开云雾见青天)的感觉,下面就是获取了,上面说过9千多行那个滚动页面就会走的那个方法,那几个参数,其中的intTop就是我们需要的高度的值,页码需要通过那个key-value获取,所以我开始修改了源码。

我们需要实时的获取当前页的数据

 this._location = {pageNumber: pageNumber,scale: normalizedScaleValue,top: intTop,left: intLeft,rotation: this._pagesRotation,pdfOpenParams: pdfOpenParams
};
//下方是我添加的代码(这里你需要在viewer.html页面中加入二个隐藏的input,id为page_top和page_cache)var page_top = document.getElementById("page_top");page_top.value = this._location.top;var page_cache = document.getElementById("page_cache");page_cache.value = this.getPageCache(this._location.pageNumber);

最后一行那个getPageCache方法是我修改的源码:

 this._location = {pageNumber: pageNumber,scale: normalizedScaleValue,top: intTop,left: intLeft,rotation: this._pagesRotation,pdfOpenParams: pdfOpenParams
};
//下方是我添加的代码(这里你需要在viewer.html页面中加入二个隐藏的input,id为page_top和page_cache)var page_top = document.getElementById("page_top");page_top.value = this._location.top;var page_cache = document.getElementById("page_cache");page_cache.value = this.getPageCache(this._location.pageNumber);}},{//下面是我添加的方法
//这个方法用来获取对应num的页码cachekey:'getPageCache',value:function getPageCache(pageNum){//循环结果(这里的page_cache是一个数组,下面细说)var str = JSON.stringify(page_cache);//  console.log("格式为:"+typeof(JSON.parse(str)))
//  console.log("json的数据:"+str)for(var key in JSON.parse(str)){if(JSON.parse(str)[key]==pageNum){return key;}}}

我们上面有说那个key-value格式的数据,因为不是一个代码块中,所在我在js的最上方加上了一个全局变量page_cache

//定义全局变量   去接受页码对应编码值
var page_cache = [];

然后在页面加载pdf的时候也给这个数组赋值一下:

{key: 'cachePageRef',value: function cachePageRef(pageNum, pageRef) {if (!pageRef) {return;}var refStr = pageRef.num + ' ' + pageRef.gen + ' R';this._pagesRefCache[refStr] = pageNum;//当赋值完毕之后,给全局赋值,这样我就获取到这个编码了page_cache =  this._pagesRefCache;}}, {key: '_cachedPageNumber',value: function _cachedPageNumber(pageRef) {var refStr = pageRef.num + ' ' + pageRef.gen + ' R';return this._pagesRefCache && this._pagesRefCache[refStr] || null;
}},

这样就如上面,通过这个全局去获取对应的编码值。(整个获取就到此结束了(设置锚点))

补充一下:有的人可能不会获取iframe下的文件,发一下我的这个:

//这个是子页面
<iframe id="iframe01" name='iframe01' style="width:100%;height:100%;"
src='http://服务器/PDF测试/js/PDF.js/web/viewer.html?file=http://服务器/PDF测试/src/demo.pdf&page=1&top=0&zoom=1'></iframe>//js
top = $("#iframe01").contents().find("#page_top").val();
cache = $("#iframe01").contents().find("#page_cache").val().split(" ")[0];
console.log("父页面获取的top:"+$("#iframe01").contents().find("#page_top").val());
console.log("父页面获取的页码编码:"+$("#iframe01").contents().find("#page_cache").val());

这样就获取了那个编码中的num和那个高度的值了。

下面就是实现定位了(锚点点击定位):直接上代码

//html
<button class='set1'>点击定位1</button>
<button hidden="hidden" class='set2'>点击定位2</button>//jq//这个才是定位
$(".set1").click(function(){$(".set2").click();//始终在页面只有一个是模拟添加的a标签if($("#iframe01").contents().find(".addLink").length!=0){$("#iframe01").contents().find(".addLink").remove();}//创建一个模拟目录中的标题a标签str = "<a hidden:'hidden'  href='"+ '#[{"num":'+cache+',"gen":0},{"name":"XYZ"},74,'+top+',0]'+ "'class='internalLink addLink' id='p37318'><p></p></a>";//添加到子页面中//先判断是否有   没有再添加   有就不添加if($("#iframe01").contents().find("#p37318").length==0){$("#iframe01").contents().find("body").append(str);}//模拟目录a标签的点击事件$("#iframe01").contents().find("#p37318").find("p")[0].click();
})//这个是假的
$(".set2").click(function(){if($("#iframe01").contents().find(".addLink").length!=0){$("#iframe01").contents().find(".addLink").remove();}str = "<a  href='"+ '#[{"num":17,"gen":0},{"name":"XYZ"},74,192,0]'+ "'class='internalLink addLink' id='p17192'><p>GG</p></a>";if($("#iframe01").contents().find("#p17192").length==0){$("#iframe01").contents().find("body").append(str);}$("#iframe01").contents().find("#p17192").find("p")[0].click();
})

思路:发现目录的a标签的事件和class,后台传的数据有那二个参数,创建一个类似的a标签,将参数放进去,然后放到子页面中,点击的时候去找到我们新增的a标签,触发点击,实现跳转,这里的set1是跳转的。因为在我的本地一个点击当你滚动的时候,再次点击就不行了,失效。所以又加了一个隐藏的点击,每次点击先触发一下隐藏的点击。发现可用。

有很多人都遇到这种问题了。也不用去找我了,通过需要的内容设置定位点以及跳转到定位点我在github写了一个小demo,有兴趣的可以下载试试https://github.com/Ma-Tao007/pdfdemo2

整个模拟行定位实现完毕。用了我一整天的时间,但是最后的结果还是让我极其欣慰的。由于发不了项目源码,所以只能在github上传了一个简单的demo,有兴趣的可以下载看看。有问题的可以留言。

PDF.js实现行定位功能(通过外部点击跳转到某一行)相关推荐

  1. 使用pdf.js预览实现读取服务器外部文件

    不知道大家使用百度网盘的文件预览功能,f12看过控制台没有. 发现百度网盘使用的预览文件功能全是基于开源pdf .js的 接下来正题,我们在使用pdf.js默认是读取发布容器内部的文件,读取外部的文件 ...

  2. js锚点定位_overflow属性详解,利用CSS实现锚点定位

    1.overflow的裁剪界线--border-box overflow属性用于指定块容器元素的内容溢出时的表现方式--滚动,裁剪,自适应."BFC的最佳结界"只是其衍生出来的特性 ...

  3. 文本编辑器实现跳转到指定行的功能

    文章目录 1 文本编辑器实现跳转到指定行的功能 1 文本编辑器实现跳转到指定行的功能 用户需求: 提供输入对话框. 用户可输入目标行号. 确定后光标跳转到指定行. 行间跳转算法设计: 通过输入对话框获 ...

  4. pdf.js实现多个不同词的高亮显示

    这里我是没有进行压缩过的版本进行修改,该版本目录分析参考:https://blog.csdn.net/a973685825/article/details/81285288 目标:实现多个词的高亮显示 ...

  5. android 在线解析pdf文件格式,Android PDF预览阅读:用Mozilla PDF.js浏览本地在线PDF文件 | KaelLi的博客...

    在之前的Android端预览PDF方案一文中,曾经提到了使用Mozilla的PDF.js来加载PDF的办法,今天就详细的说一下具体的实现. 简介 PDF.js是一个使用HTML5构建的PDF查看器.由 ...

  6. pdf.js在线预览PDF文件实现

    pdf.js是一款功能比较强大的在线预览PDF插件,自带"打印","搜索","翻页"等功能,强大且实现方便,并且兼容性比较好(兼容ie10及 ...

  7. engineercms利用pdf.js制作连续看图功能

    系统平台上打开pdf文件,chrome浏览器自动会打开这个附件. 那么,附件要用相对地址,绝对的pdf文件名称,可能给权限设计带来一点困扰,一般用/pdf?id=***来看附件,此时就必须用pdf.j ...

  8. JAVA常用API或编程工具003--实现pdf在线阅读功能之pdf.js

    pdf.js简介 PDF.js 是基于开放的 HTML5 及 JavaScript 技术实现的开源产品.简单说就是一个 PDF 解析器.运用HTML5JavaScript(即pdf.js仅使用安全的w ...

  9. 利用PDF.JS插件解决了本地pdf文件在线浏览问题(根据需要隐藏下载功能,只保留打印功能)

    利用PDF.JS插件解决了本地pdf文件在线浏览问题(根据需要隐藏下载功能,只保留打印功能) 参考文章: (1)利用PDF.JS插件解决了本地pdf文件在线浏览问题(根据需要隐藏下载功能,只保留打印功 ...

最新文章

  1. NLP学习思维导图,非常的全面和清晰
  2. 面试:TCP协议经典十五连问!
  3. NTU 课程笔记:CV6422 样本分布
  4. Android 网络请求HttpURLConnection 和 HttpClient详解
  5. 2018上IEC计算机高级语言(C)作业 第2次作业
  6. python输入年份月份输出天数_6.2(输入年份 月份 输出该月天数)
  7. Notepad++ 大小写转换
  8. jq使用教程03_JQData说明书概要
  9. Oracle使用Shell脚本导出Excel表格
  10. Word怎么转PDF?看完这篇你就知道了
  11. Android开发 手机开发者模式
  12. 比肩Sci-hub的论文下载神器——Library Genesis
  13. 用ReadyBoost提高Windows 7系统性能
  14. 方阵平方等于自身,这个方阵的特征值
  15. 吃土豆_nyoj_234(动态规划).java
  16. C#,ASP.NAT基于腾讯服务器实现自动发送邮件功能的几种方法及遇到的坑
  17. 8Manage:大宗商品采购,专注构建企业采购信息化!
  18. presson绘图练习
  19. 半乳糖修饰人血清白蛋白 Gal-HSA,Gal-PEG-HSA,单糖/多糖修饰蛋白等
  20. 计算机记录乐器,2013年计算机考试题模拟考试2套题.doc

热门文章

  1. input标签disabled和readonly属性的区别
  2. python决策树export_机器学习--决策树--dot转存pdf
  3. 通过以太坊账户地址恢复私钥,并通过私钥恢复出对应公钥
  4. 为什么今日头条、子弹短信、快播王欣都选在同一天举办社交产品发布会?
  5. js垃圾回收机制的优化
  6. iOS持续集成-Xcodebuild命令
  7. ERP学习入门篇——目录
  8. python中map()函数总结
  9. linux启动nginx命令行_Linux环境下启动、停止、重启nginx
  10. 关于微信服务号自定义发送给朋友/分享到朋友圈, 发送/分享失败的一些问题及解决方式