99

I have to load a PDF within a page.

Ideally I would like to have a loading animated gif which is replaced once the PDF has loaded.

alex
  • 479,566
  • 201
  • 878
  • 984
Alex Andronov
  • 1,665
  • 2
  • 15
  • 18

14 Answers14

215

Have you tried:

$("#iFrameId").on("load", function () {
    // do something once the iframe is loaded
});
travis
  • 35,751
  • 21
  • 71
  • 94
  • 21
    +1 because while this doesn't appear to work for PDF's loading in the iframe, it's useful for other content types. – Cory House Mar 22 '11 at 20:36
  • 3
    +1 Not exactly what the original asker wanted to know (with relation to pdf), but this answer does match the question "How do I fire an event when a iframe has finished loading in jQuery?" . Thanks – Harvey Darvey Jan 16 '12 at 10:45
  • Haven't tried this with PDFs but it will run perfectly for normal URLs. – Bob-ob Sep 27 '12 at 22:38
  • I am using this inside `$(function({})` so that the frame loads first. But am not getting the hoped for result. Chrome 25 Mac – William Entriken Sep 04 '13 at 14:43
  • This does not work for loading pdf in the iframe. Tested in IE 11. – Robert Smith Dec 10 '19 at 15:42
  • @RobertSmith are there any javascript errors in the console? was that with a PDF plug-in or with a native viewer? It has been over 11 years since I posted that answer and unfortunate that IE11 is still problematic. – travis Dec 10 '19 at 19:20
38

I'm pretty certain that it cannot be done.

Pretty much anything else than PDF works, even Flash. (Tested on Safari, Firefox 3, IE 7)

Too bad.

alex
  • 479,566
  • 201
  • 878
  • 984
Antti Kissaniemi
  • 18,944
  • 13
  • 54
  • 47
8

This did it for me (not pdf, but another "onload resistant" content):

<iframe id="frameid" src="page.aspx"></iframe>
<script language="javascript">
    iframe = document.getElementById("frameid");

    WaitForIFrame();

    function WaitForIFrame() {
        if (iframe.readyState != "complete") {
            setTimeout("WaitForIFrame();", 200);
        } else {
            done();
        }
    }

    function done() {
        //some code after iframe has been loaded
    }
</script>  

Hope this helps.

Yi Jiang
  • 49,435
  • 16
  • 136
  • 136
7

I am trying this and seems to be working for me: http://jsfiddle.net/aamir/BXe8C/

Bigger pdf file: http://jsfiddle.net/aamir/BXe8C/1/

Aamir Afridi
  • 6,364
  • 3
  • 42
  • 42
  • 1
    Not very different than the answer by @travis but I will +1 because of the elegant usage of attr src change and css. I can see someone at least faking a nice loader doing it that way. – Anthony Hatzopoulos Jul 25 '12 at 00:58
  • The load event fired before the PDF completely loaded. – etlds Oct 09 '12 at 16:10
  • Tried your links on OSX with latest Chrome and on first page load, it did not work, kept `Loading PDF...` but when I refreshed the page, said `PDF Loaded!`. But this seems to work with urls :) so it's very useful to me. Thanks! – GabLeRoux Oct 05 '13 at 21:04
  • This doesn't work if the file is set to download, instead of be rendered in the iframe. – Ring May 17 '14 at 01:55
  • This doesn't work in IE 11. Keeps "Loading PDF...". I'm looking for a solution that also works in IE 11. – Marc Jul 14 '14 at 05:55
6
$("#iFrameId").ready(function (){
    // do something once the iframe is loaded
});

have you tried .ready instead?

keithics
  • 8,576
  • 2
  • 48
  • 35
  • This method won't work as expected. From the JQuery docs: "The .ready() method can only be called on a jQuery object matching the current document, so the selector can be omitted." Sounds like it will be fired after $(document) no matter the selector used. – Cazuma Nii Cavalcanti Mar 06 '13 at 21:16
  • I'm fairly certain this is idle theory. – Barney Apr 11 '13 at 09:05
  • Repeat of earlier answer! – SyntaxRules Jul 22 '13 at 16:56
  • As others stated, I tested this and it did not work. The Ready was called on document ready, not the iframe... Use the On Load option. – Greg Aug 05 '14 at 20:10
5

I tried an out of the box approach to this, I havent tested this for PDF content but it did work for normal HTML based content, heres how:

Step 1: Wrap your Iframe in a div wrapper

Step 2: Add a background image to your div wrapper:

.wrapperdiv{
  background-image:url(img/loading.gif);
  background-repeat:no-repeat;
  background-position:center center; /*Can place your loader where ever you like */
}

Step 3: in ur iframe tag add ALLOWTRANSPARENCY="false"

The idea is to show the loading animation in the wrapper div till the iframe loads after it has loaded the iframe would cover the loading animation.

Give it a try.

Michael Lu
  • 93
  • 1
  • 7
4

Using both jquery Load and Ready neither seemed to really match when the iframe was TRULY ready.

I ended up doing something like this

$('#iframe').ready(function () {
    $("#loader").fadeOut(2500, function (sender) {
        $(sender).remove();
    });
});

Where #loader is an absolutely positioned div over top the iframe with a spinner gif.

Chris Marisic
  • 32,487
  • 24
  • 164
  • 258
2

@Alex aw that's a bummer. What if in your iframe you had an html document that looked like:

<html>
  <head>
    <meta http-equiv="refresh" content="0;url=/pdfs/somepdf.pdf" />
  </head>
  <body>
  </body>
</html>

Definitely a hack, but it might work for Firefox. Although I wonder if the load event would fire too soon in that case.

travis
  • 35,751
  • 21
  • 71
  • 94
1

I had to show a loader while pdf in iFrame is loading so what i come up with:

    loader({href:'loader.gif', onComplete: function(){
            $('#pd').html('<iframe onLoad="loader.close();" src="pdf" width="720px" height="600px" >Please wait... your report is loading..</iframe>');
    }
    });

I'm showing a loader. Once I'm sure that customer can see my loader, i'm calling onCompllet loaders method that loads an iframe. Iframe has an "onLoad" event. Once PDF is loaded it triggers onloat event where i'm hiding the loader :)

The important part:

iFrame has "onLoad" event where you can do what you need (hide loaders etc.)

rinchik
  • 2,642
  • 8
  • 29
  • 46
1

function frameLoaded(element) {
    alert('LOADED');
};
 <iframe src="https://google.com" title="W3Schools Free Online Web Tutorials" onload="frameLoaded(this)"></iframe> 
Mahdi Bashirpour
  • 17,147
  • 12
  • 117
  • 144
0

Here is what I do for any action and it works in Firefox, IE, Opera, and Safari.

<script type="text/javascript">
  $(document).ready(function(){
    doMethod();
  });
  function actionIframe(iframe)
  {
    ... do what ever ...
  }
  function doMethod()
  {   
    var iFrames = document.getElementsByTagName('iframe');

    // what ever action you want.
    function iAction()
    {
      // Iterate through all iframes in the page.
      for (var i = 0, j = iFrames.length; i < j; i++)
      {
        actionIframe(iFrames[i]);
      }
    }

    // Check if browser is Safari or Opera.
    if ($.browser.safari || $.browser.opera)
    {
      // Start timer when loaded.
      $('iframe').load(function()
      {
        setTimeout(iAction, 0);
      }
      );

      // Safari and Opera need something to force a load.
      for (var i = 0, j = iFrames.length; i < j; i++)
      {
         var iSource = iFrames[i].src;
         iFrames[i].src = '';
         iFrames[i].src = iSource;
      }
    }
    else
    {
      // For other good browsers.
      $('iframe').load(function()
      {
        actionIframe(this);
      }
      );
    }
  }
</script>
user22367
  • 109
  • 1
  • 5
0

If you can expect the browser's open/save interface to pop up for the user once the download is complete, then you can run this when you start the download:

$( document ).blur( function () {
    // Your code here...
});

When the dialogue pops up on top of the page, the blur event will trigger.

Ethan
  • 642
  • 7
  • 15
0

Since after the pdf file is loaded, the iframe document will have a new DOM element <embed/>, so we can do the check like this:

    window.onload = function () {


    //creating an iframe element
    var ifr = document.createElement('iframe');
    document.body.appendChild(ifr);

    // making the iframe fill the viewport
    ifr.width  = '100%';
    ifr.height = window.innerHeight;

    // continuously checking to see if the pdf file has been loaded
     self.interval = setInterval(function () {
        if (ifr && ifr.contentDocument && ifr.contentDocument.readyState === 'complete' && ifr.contentDocument.embeds && ifr.contentDocument.embeds.length > 0) {
            clearInterval(self.interval);

            console.log("loaded");
            //You can do print here: ifr.contentWindow.print();
        }
    }, 100); 

    ifr.src = src;
}
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
令狐葱
  • 1,117
  • 12
  • 12
0

The solution I have applied to this situation is to simply place an absolute loading image in the DOM, which will be covered by the iframe layer after the iframe is loaded.

The z-index of the iframe should be (loading's z-index + 1), or just higher.

For example:

.loading-image { position: absolute; z-index: 0; }
.iframe-element { position: relative; z-index: 1; }

Hope this helps if no javaScript solution did. I do think that CSS is best practice for these situations.

Best regards.

AldorEla
  • 56
  • 5