¿Cómo disparo un evento cuando un iframe ha terminado de cargarse en jQuery?

95

Tengo que cargar un PDF dentro de una página.

Idealmente, me gustaría tener un gif animado de carga que se reemplaza una vez que se ha cargado el PDF.

Alex Andronov
fuente

Respuestas:

38

Estoy bastante seguro de que no se puede hacer.

Prácticamente cualquier otra cosa que no sea PDF funciona, incluso Flash. (Probado en Safari, Firefox 3, IE 7)

Demasiado.

Antti Kissaniemi
fuente
FWIW, todos ellos (incluso PDF) me funcionaron con Chrome en OS X.
pkaeding
Sí, funciona en Chrome pero no en IE. Si la aplicación está en la web, también debe funcionar en IE.
Robert Smith
214

Has probado:

$("#iFrameId").on("load", function () {
    // do something once the iframe is loaded
});
travis
fuente
19
+1 porque si bien esto no parece funcionar para la carga de PDF en el iframe, es útil para otros tipos de contenido.
Cory House
3
+1 No es exactamente lo que el autor de la pregunta original quería saber (con relación a pdf), pero esta respuesta coincide con la pregunta "¿Cómo disparo un evento cuando un iframe ha terminado de cargarse en jQuery?" . Gracias
Harvey Darvey
No he probado esto con archivos PDF, pero funcionará perfectamente para URL normales.
Bob-ob
Estoy usando esto en el interior $(function({})para que el marco se cargue primero. Pero no estoy obteniendo el resultado esperado. Chrome 25 Mac
William Entriken
Esto no funciona para cargar pdf en el iframe. Probado en IE 11.
Robert Smith
7

Esto lo hizo por mí (no pdf, sino otro onloadcontenido " resistente"):

<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>  

Espero que esto ayude.

Yi Jiang
fuente
7
Se debe evitar el argumento de cadena setTimeout ():setTimeout(WaitForIFrame, 200);
Stefan Majewsky
7

Estoy intentando esto y parece que me está funcionando: http://jsfiddle.net/aamir/BXe8C/

Archivo pdf más grande: http://jsfiddle.net/aamir/BXe8C/1/

Aamir Afridi
fuente
1
No es muy diferente a la respuesta de @travis, pero haré +1 debido al uso elegante de attr src change y css. Puedo ver a alguien al menos fingiendo un buen cargador haciéndolo de esa manera.
Anthony Hatzopoulos
El evento de carga se disparó antes de que el PDF se cargara por completo.
etlds
Probé sus enlaces en OSX con la última versión de Chrome y en la carga de la primera página, no funcionó, se mantuvo, Loading PDF...pero cuando actualicé la página, dijo PDF Loaded!. Pero esto parece funcionar con URL :) así que es muy útil para mí. ¡Gracias!
GabLeRoux
Esto no funciona si el archivo está configurado para descargar, en lugar de renderizarse en el iframe.
Ring
Esto no funciona en IE 11. Mantiene "Cargando PDF ...". Estoy buscando una solución que también funcione en IE 11.
Marc
6
$("#iFrameId").ready(function (){
    // do something once the iframe is loaded
});

¿has probado .ready en su lugar?

keithics
fuente
Este método no funcionará como se esperaba. De los documentos de JQuery: "El método .ready () solo se puede llamar en un objeto jQuery que coincida con el documento actual, por lo que el selector se puede omitir". Parece que se activará después de $ (documento) sin importar el selector utilizado.
Cazuma Nii Cavalcanti
Estoy bastante seguro de que esta es una teoría ociosa.
Barney
¡Repita la respuesta anterior!
SyntaxRules
Como dijeron otros, probé esto y no funcionó. Se llamó al Ready en document ready, no al iframe ... Use la opción On Load.
Greg
5

Probé un enfoque listo para usar para esto, no lo he probado para contenido PDF pero funcionó para contenido normal basado en HTML, así es como:

Paso 1 : envuelva su iframe en una envoltura div

Paso 2 : agregue una imagen de fondo a su contenedor div:

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

Paso 3 : en tu etiqueta iframe, agrega ALLOWTRANSPARENCY="false"

La idea es mostrar la animación de carga en el div contenedor hasta que se cargue el iframe después de que haya cargado, el iframe cubriría la animación de carga.

Darle una oportunidad.

Michael Lu
fuente
4

El uso de jquery Load y Ready ninguno parecía coincidir realmente cuando el iframe estaba REALMENTE listo.

Terminé haciendo algo como esto

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

Donde #loader es un div absolutamente posicionado sobre el iframe con un gif giratorio.

Chris Marisic
fuente
2

@Alex aw eso es un fastidio. ¿Qué pasaría si en tu iframetuvieras un documento html que se pareciera a:

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

Definitivamente un truco, pero podría funcionar para Firefox. Aunque me pregunto si el evento de carga se dispararía demasiado pronto en ese caso.

travis
fuente
eso es lo que estoy buscando :(
Aamir Afridi
1

Tuve que mostrar un cargador mientras se cargaba pdf en iFrame, así que lo que se me ocurre:

    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>');
    }
    });

Estoy mostrando un cargador. Una vez que estoy seguro de que el cliente puede ver mi cargador, llamo al método de cargadores onCompllet que carga un iframe. Iframe tiene un evento "onLoad". Una vez que se carga el PDF, se activa el evento onloat donde estoy escondiendo el cargador :)

La parte importante:

iFrame tiene un evento "onLoad" en el que puede hacer lo que necesite (ocultar cargadores, etc.)

Rinchik
fuente
0

Esto es lo que hago para cualquier acción y funciona en Firefox, IE, Opera y 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>
usuario22367
fuente
0

Si puede esperar que la interfaz de abrir / guardar del navegador aparezca para el usuario una vez que se complete la descarga, entonces puede ejecutar esto cuando inicie la descarga:

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

Cuando el diálogo aparece en la parte superior de la página, se activará el evento de desenfoque.

Ethan
fuente
0

Dado que después de que se cargue el archivo pdf, el documento iframe tendrá un nuevo elemento DOM <embed/>, por lo que podemos hacer la verificación de esta manera:

    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;
}
令狐 葱
fuente
0

La solución que he aplicado a esta situación es simplemente colocar una imagen de carga absoluta en el DOM, que será cubierta por la capa de iframe después de que se cargue el iframe.

El índice z del iframe debería ser (índice z de carga + 1), o simplemente superior.

Por ejemplo:

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

Espero que esto ayude si ninguna solución de javaScript lo hizo. Creo que CSS es la mejor práctica para estas situaciones.

Atentamente.

ElaAle
fuente