pdf.js内部的按钮上传、定位、浏览功能的方法

优采云 发布时间: 2021-05-06 23:03

  pdf.js内部的按钮上传、定位、浏览功能的方法

  这部分是我们公司之前需要实现的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的值,另一个是倒数第二个数字。我接下来去。寻找源代码,一个接一个的控制台,我终于在viewer.js的9285行中找到了线索(因为每个版本中的行数不同,以下是我复制的js方法,因为加密的计算机可以'不截屏,仅截取代码):

  key: '_updateLocation',

value: function _updateLocation(firstPage) {

var currentScale = this._currentScale;

var currentScaleValue = this._currentScaleValue;

var normalizedScaleValue = parseFloat(currentScaleValue)

...........

  滚动页面时,此方法的控制台方法将使用此方法。此方法背后有几个非常重要的参数。

   this._location = {

pageNumber: pageNumber,

scale: normalizedScaleValue,

top: intTop,

left: intLeft,

rotation: this._pagesRotation,

pdfOpenParams: pdfOpenParams

};

  通过打印,可以发现pageNumber是当前页码,而intTop是代码更改数量中倒数第二个参数,它被解释为高度(哈哈,现在我知道了不是记录的行,而是当前记录(通过页码高度实现的“行定位”),现在第一个参数在那里,主要目标是该num的值,与num的值完全不同我们在页面上看到的值,我猜它必须是json或数组。与键值相对应的页码是什么,然后我沿着藤蔓通过此方法找到了大本营:

  {

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),这两种方法非常重要,一种是页码(在下面),另一种是创建的键值格式的代码(在上部),这是通过控制台了解的,当您加载pdf文件时,您将调用上述方法以将页码与代码进行匹配(相应的格式为“ 27 0 R”-“ 4”,其中4为值是页面数字,前面的键是代码。

  到目前为止,感觉就像(将云朵拉开,看到蓝天)。以下是收购。滚动上面提到的9,000行以上的页面的方法,几个参数,其中intTop是我们需要的高度值,并且需要通过该键值获取页码,因此我开始修改源代码代码。

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

   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的页码cache

key:'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;

}

}

}

  我们在上面提到了键值格式数据,因为它不在代码块中,所以我在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下获取文件,请将此信息发送给我:

  //这个是子页面

//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和height的值。

  以下是定位的实现(锚点定位):直接上传代码

  //html

点击定位1

点击定位2

//jq

//这个才是定位

$(".set1").click(function(){

$(".set2").click();

//始终在页面只有一个是模拟添加的a标签

if($("#iframe01").contents().find(".addLink").length!=0){

$("#iframe01").contents().find(".addLink").remove();

}

//创建一个模拟目录中的标题a标签

str = "<a hidden:&#39;hidden&#39; href=&#39;"

+ &#39;#[{"num":&#39;+cache+&#39;,"gen":0},{"name":"XYZ"},74,&#39;+top+&#39;,0]&#39;

+ "&#39;class=&#39;internalLink addLink&#39; id=&#39;p37318&#39;>

</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=&#39;"

+ &#39;#[{"num":17,"gen":0},{"name":"XYZ"},74,192,0]&#39;

+ "&#39;class=&#39;internalLink addLink&#39; id=&#39;p17192&#39;><p>GG</a>";

if($("#iframe01").contents().find("#p17192").length==0){

$("#iframe01").contents().find("body").append(str);

}

$("#iframe01").contents().find("#p17192").

find("p")[0].click();

})</p>

  想法:找到目录标签的事件和类,在后台传输的数据具有这两个参数,创建一个类似的标签,将参数放入,然后将其放入子页面,并在单击时找到我们。新添加的标签触发单击以实现跳转,而set1此处为跳转。因为在我本地滚动时一键单击,再次单击将不起作用,无效。因此,添加了一个隐藏的单击,并且每次单击都会首先触发一个隐藏的单击。发现可用。

  许多人都遇到过这种问题。你不用再找我了设置锚点并通过所需的内容跳转到锚点。我在github上写了一个小演示。如果您有兴趣,可以下载并尝试

  整个模拟行定位已完成。我花了整整一天的时间,但最终结果仍然让我感到非常满意。由于该项目的源代码无法发布,因此我只能在github上上传一个简单的演示,有兴趣的人可以下载它。如有任何疑问,可以留言。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线