Work study concluded stepped pit and use of -pdf.js

Weekend, and finally there is such a time to sum up the whole of finishing, this month is very busy, a lot of demand, age is not small, personal things in life a lot. Time is the most fair, because everyone had such a long day, cherish every minute. Well, not sentimental. Get to the bar.
Let me talk about the project structure: angular5.0 + ionic3.0 this month made a demand pdf show, backstage pass over the url a junior partner in pdf format,
the length of this url:

url = ”https://sg.ibs.baidu.com.cn/download/fla-ybkj-dmz-dev-pri/24a1bed5f3fc46d582d6ff7747445b14?attname=BS012LYT.pdf"

In fact, url address file is a pdf format, and then show you the front. Originally thought would be simple to achieve, is thought to pit one by one, one by one the following to say about it.

1. First backstage pass over the url do some transformation, transformation in angular as follows:

 html的代码
    <ion-content  (ionScroll)="scrollEvent($event)">
        <iframe [src]=“url” height="100%" width="100%" seamless scrolling="no" id=“deatilShow”></iframe>
    </ion-content>
    ts中的代码
    this.url = this.sanitizer.bypassSecurityTrustResourceUrl("assets/viewer/web/viewer.html?file=" + encodeURIComponent(res.data.url));

Only after the transformation url is loaded into an iframe valid

2. The pdf.js is a general term, after installed, there will be so many documents, as:
pdfjs
HTML pages written as follows:

<ion-content  (ionScroll)="scrollEvent($event)">
    <iframe [src]=“url” height="100%" width="100%" seamless scrolling="no" id=“deatilShow”></iframe>
</ion-content>

Where the
scrolling attribute specifies whether scrollbars in an iframe. There are three values yes, NO, Auto
Seamless attribute specifies looks like part of the document contains.
scrollEvent rolling event listener ion-content content. And then began to increase after the trigger event rolling in scrollEvent inside, as follows:

scrollEvent(event) {
    this.show = true;
    let het1 = document.body.clientHeight;
    let het2 = document.getElementById("deatilShow").clientHeight; 
    this.ngzone.run(() => {
      let top = event.scrollTop; 
      if (het2 <= het1 + top) {
        this.buttonShow = false;
      }
    })
  }

This.ngzone.run above code () usage, see my other article simple to use work and study are summarized in NgZone of -angular

When I scroll the page when, scrollEvent event did not trigger, because I was rolling iframe page, which is embedded in another page, so it will not trigger scrollEvent event. So I looked for a compromise solution, iframe to add a margin-bottom, when scrolling iframe in the end part of the time, sliding a little further on, it will trigger this event, that is, ion-content of this page is scrolled, but the effect is not very good, in the ios and Android experience is not very good, so in the end did not use this method. then what should we do?
Search + through their own thinking and to help other small partners, and finally in a stupid way to solve.

3. The following description of the process (exploration method) I explored: the
first thing I get this iframe element, listening to its Scroll event, acquired a iframe html, as shown:
Here Insert Picture Description

So to add it to scroll event is invalid, then Baidu method and there are no effective methods, and finally Google a bit to find a way, is listening irame the id rolling event element viewerContainer of the job, this id is viewerContainer the element is actually an element viewer.html in all pdf file pages are loaded into it, it viewer.html code are as follows:

<div id="viewerContainer" tabindex="0">
      <div id="viewer" class="pdfViewer"></div>
 </div>

And then went to get this element

        setTimeout(() => {
                if(this.elementRef.nativeElement.querySelector('.scroll-content #deatilShow') && this.elementRef.nativeElement.querySelector('.scroll-content #deatilShow').contentDocument && this.elementRef.nativeElement.querySelector('.scroll-content #deatilShow').contentDocument.getElementById("viewerContainer")) {
                clearInterval(this.timer)
                viewerContainer = this.elementRef.nativeElement.querySelector('.scroll-content #deatilShow').contentDocument.getElementById("viewerContainer");
                viewerContainer.addEventListener('scroll',(event) => {
                  let scrollTop = event.target.scrollTop ;
                  let clientHeight = event.target.clientHeight ;
                  let scrollHeight = event.target.scrollHeight ;
                  if(scrollTop+clientHeight == scrollHeight){
                      // 添加滚到底部要处理的事件
                  }
                });
              }
            },2000)

Why add a timer do? Because speed is not good when, pdf loads slowly, it may not load the full page, you may get less than this time element. This time in the browser when the newspaper ran cross-domain problem, so in the Google browser settings a bit cross-domain. This time the page events are possible, can be triggered. Invalid then packaged measured on ios and Android phones when it no effect, this time to wonder. why? Phone attached to the computer debugging a bit and found this element or viewerContainer not get to. Checked, guess should be pdf.js security policy, do not let the outside world get viewerContainer this element as pdf files are loaded to the following elements, afraid of the outside world pdf file modification operations. Why is that a computer can do, perhaps because Google to set up cross-domain, you can ignore this risk, the specific reasons for the need to carefully follow-up check. This method has been pass out, it continues to find ways to

4. Exploring Method two
get to meet this element is no way to monitor its scroll event. Now that the outside world can not get, I get this element in viewer.html in and give it a listen for the scroll event. First try, try not to spend money.
So I viewer.html added to it in this piece of code

<script>
  let number = 0;
  document.getElementById("viewerContainer").addEventListener("scroll",(event)=>{
    let [ top, cliHeight, scrHeight] = [ event.target.scrollTop, event.target.clientHeight, event.target.scrollHeight];
    number++;
    top + cliHeight + 50 >= scrHeight ? window.parent.postMessage({toBottom : true},"*") : "";
    number == 5 ? window.parent.postMessage({scrolled:true},"*") : "";
  });
</script>

Then listen for events postMessage issued on a page on it

ngOnInit() {
        window.addEventListener("message",(event)=>{
               event.data.toBottom?this.show = true:"";
               event.data.scrolled?this.button = true:"";
        })
   }

Finally solved the problem, but this is only a temporary solution, the latter if there is any better way to go but also optimized.
This approach has two problems need to pay attention to what one is used in viewer.html page window.parent.postMessage issues a message when the other is listening in the parent page, data event.data to distinguish what kind of monitor messages.

5. Finally, talk about me doing this source of pdfjs what changes
the first point: I commented out cross-domain this one, in viewer.js inside (in the 1751 lines to 1753 lines)

 try {
      var viewerOrigin = new _pdfjsLib.URL(window.location.href).origin || 'null';

      if (HOSTED_VIEWER_ORIGINS.includes(viewerOrigin)) {
        return;
      }

      var _ref8 = new _pdfjsLib.URL(file, window.location.href),
          origin = _ref8.origin,
          protocol = _ref8.protocol;

      // if (origin !== viewerOrigin && protocol !== 'blob:') {
      //   throw new Error('file origin does not match viewer\'s');
      // }
    } catch (ex) {

The second point: the demand needed to show the need to contract signature file, which is overshadowed by chapter , so pdf.work.js there so few lines of code commented out
about the comments four lines of code (lines 28684 to 28688 on the line)

 if (!Number.isInteger(data.fieldFlags) || data.fieldFlags < 0) {
      data.fieldFlags = 0;
    }

    data.readOnly = _this2.hasFieldFlag(_util.AnnotationFieldFlag.READONLY);

    // if (data.fieldType === 'Sig') {
    //   data.fieldValue = null;

    //   _this2.setFlags(_util.AnnotationFlag.HIDDEN);
    // }

    return _this2;
  }

pdf.js I'm using version 2.0

The third point: Clear Cache pdf Why remove pdf cache it? For example, I open a pdf file, slide on page 6, and then exit the page, and then come in or on page 6. That there is no way to make file loads from the first page of it. I began to explore the road, in fact, the development of experienced people, to find the problem quickly is also very accurate, perhaps because the development needs more, contact problems can have. I went inside to look for the plug-in, looking at viewer.js inside. Cache is meant history, so I will check the history, I have found this line of code:

localStorage.setItem('pdfjs.history', databaseStr);

I feel this is what I was looking for, so I went inside to find localstorage browser, and sure enough, see Figure: Here Insert Picture Description
I line 13457 in viewer.js in it commented out

_regenerator.default.mark(function _callee() {
        var databaseStr;
        return _regenerator.default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                databaseStr = JSON.stringify(this.database);
                // localStorage.setItem('pdfjs.history', databaseStr);  

              case 2:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

Then there is no cache, the problem is solved.
Another way is stupid behind url pdf plus a time stamp or a nonce.
After questions about pdf.js encountered, the time will add.

Published 130 original articles · won praise 103 · views 260 000 +

Guess you like

Origin blog.csdn.net/xiaolinlife/article/details/100175288