Como faço para disparar um evento quando um iframe termina de carregar no jQuery?

95

Tenho que carregar um PDF em uma página.

Idealmente, gostaria de ter um GIF animado de carregamento que seja substituído assim que o PDF for carregado.

Alex Andronov
fonte

Respostas:

38

Tenho certeza de que isso não pode ser feito.

Quase tudo que não seja PDF funciona, até mesmo Flash. (Testado no Safari, Firefox 3, IE 7)

Que pena.

Antti Kissaniemi
fonte
FWIW, todos eles (até PDF) funcionaram para mim com o Chrome no OS X.
marcado para
Sim, funciona no Chrome, mas não no IE. Se o aplicativo estiver na web, ele também deve funcionar no IE.
Robert Smith
214

Você tentou:

$("#iFrameId").on("load", function () {
    // do something once the iframe is loaded
});
travis
fonte
19
+1 porque, embora isso pareça não funcionar para o carregamento de PDFs no iframe, é útil para outros tipos de conteúdo.
Cory House
3
+1 Não é exatamente o que o solicitante original queria saber (em relação ao pdf), mas essa resposta corresponde à pergunta "Como faço para disparar um evento quando um iframe termina de carregar no jQuery?" . Obrigado
Harvey Darvey
Ainda não tentei fazer isso com PDFs, mas funcionará perfeitamente para URLs normais.
Bob-ob
Estou usando isso por dentro $(function({})para que o quadro seja carregado primeiro. Mas não estou obtendo o resultado esperado. Chrome 25 Mac
William Entriken
Isso não funciona para carregar PDF no iframe. Testado no IE 11.
Robert Smith
7

Isso funcionou para mim (não pdf, mas outro onloadconteúdo "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 isto ajude.

Yi Jiang
fonte
7
O argumento de string setTimeout () deve ser evitado:setTimeout(WaitForIFrame, 200);
Stefan Majewsky
7

Estou tentando fazer isso e parece estar funcionando para mim: http://jsfiddle.net/aamir/BXe8C/

Arquivo pdf maior: http://jsfiddle.net/aamir/BXe8C/1/

Aamir Afridi
fonte
1
Não é muito diferente da resposta de @travis, mas irei +1 por causa do uso elegante de Attr src change e css. Eu posso ver alguém pelo menos fingindo ser um bom carregador fazendo isso dessa forma.
Anthony Hatzopoulos
O evento load foi disparado antes de o PDF ser completamente carregado.
etlds
Tentei seus links no OSX com o Chrome mais recente e no carregamento da primeira página, não deu certo, guardei Loading PDF...mas quando atualizei a página, disse PDF Loaded!. Mas isso parece funcionar com urls :) então é muito útil para mim. Obrigado!
GabLeRoux
Isso não funciona se o arquivo estiver definido para download, em vez de ser renderizado no iframe.
Toque
Isso não funciona no IE 11. Mantém "Carregando PDF ...". Estou procurando uma solução que também funcione no IE 11.
Marc
6
$("#iFrameId").ready(function (){
    // do something once the iframe is loaded
});

você já tentou. em vez disso?

keithics
fonte
Este método não funcionará conforme o esperado. Dos documentos JQuery: "O método .ready () só pode ser chamado em um objeto jQuery correspondente ao documento atual, portanto, o seletor pode ser omitido." Parece que ele será disparado após $ (document), independentemente do seletor usado.
Cazuma Nii Cavalcanti
Tenho quase certeza de que essa é uma teoria inútil.
Barney de
Repita a resposta anterior!
SyntaxRules de
Como outros afirmaram, eu testei isso e não funcionou. O Pronto foi chamado no documento pronto, não no iframe ... Use a opção Ao carregar.
Greg
5

Eu tentei uma abordagem pronta para o uso, não testei para conteúdo em PDF, mas funcionou para conteúdo normal baseado em HTML, veja como:

Etapa 1 : envolva seu Iframe em um invólucro div

Etapa 2 : adicione uma imagem de plano de fundo ao invólucro div:

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

Etapa 3 : em sua tag iframe, adicione ALLOWTRANSPARENCY="false"

A ideia é mostrar a animação de carregamento na div do wrapper até que o iframe carregue depois de carregado, o iframe cobrirá a animação de carregamento.

De uma chance.

Michael Lu
fonte
4

Usar jquery Load e Ready nenhum dos dois parecia realmente corresponder quando o iframe estava VERDADEIRAMENTE pronto.

Acabei fazendo algo assim

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

Onde #loader é uma div posicionada absolutamente sobre o iframe com um GIF giratório.

Chris Marisic
fonte
2

@Alex aw que é uma chatice. E se iframevocê tivesse um documento html semelhante a:

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

Definitivamente um hack, mas pode funcionar para o Firefox. Embora eu me pergunte se o evento de carregamento seria disparado muito cedo nesse caso.

travis
fonte
isso é o que estou procurando :(
Aamir Afridi
1

Tive que mostrar um carregador enquanto o pdf no iFrame estava carregando, então o que eu descobri:

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

Estou mostrando um carregador. Assim que tiver certeza de que o cliente pode ver meu carregador, estou chamando o método de carregadores onCompllet que carrega um iframe. Iframe tem um evento "onLoad". Uma vez que o PDF é carregado, ele aciona o evento onloat onde estou escondendo o carregador :)

A parte importante:

iFrame tem evento "onLoad" onde você pode fazer o que precisa (ocultar carregadores etc.)

Rinchik
fonte
0

Aqui está o que eu faço para qualquer ação e funciona no Firefox, IE, Opera e 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
fonte
0

Se você espera que a interface de abrir / salvar do navegador apareça para o usuário assim que o download for concluído, você pode executar isso ao iniciar o download:

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

Quando o diálogo aparecer no topo da página, o evento de desfoque será acionado.

Ethan
fonte
0

Depois que o arquivo pdf é carregado, o documento iframe terá um novo elemento DOM <embed/>, então podemos fazer a verificação desta forma:

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

A solução que apliquei a essa situação é simplesmente colocar uma imagem de carregamento absoluta no DOM, que será coberta pela camada do iframe depois que o iframe for carregado.

O índice z do iframe deve ser (índice z do carregamento + 1) ou apenas superior.

Por exemplo:

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

Espero que isso ajude se nenhuma solução javaScript ajudou. Eu realmente acho que CSS é a melhor prática para essas situações.

Cumprimentos.

ElaAle
fonte