Pergunta

Estamos usando jQuery thickbox para exibir dinamicamente um iframe quando alguém clica em uma imagem. Neste iframe, estamos usando galleria uma biblioteca javascript para exibir várias imagens.

O problema parece ser que $(document).ready no iframe parece ser despedido cedo demais eo conteúdo iframe não é sequer ainda carregado, por isso código galleria não é aplicada adequadamente sobre os elementos DOM. $(document).ready parece usar o estado de pronto iframe pai para decidir se o iframe está pronto.

Se extrair a função chamada por documento pronto em uma função separada e chamá-lo depois de um tempo limite de 100 ms. Ele funciona, mas não podemos ter a chance na produção com um computador lento.

$(document).ready(function() { setTimeout(ApplyGalleria, 100); });

A minha pergunta: qual o evento jQuery devemos ligar a ser capaz de executar nosso código quando a dinâmica iframe está pronto e não apenas que é um pai

Foi útil?

Solução

Eu respondi uma pergunta semelhante (ver Javascript callback quando IFRAME está carregando acabado? ). Você pode obter controle sobre o evento de carregamento de iframe com o seguinte código:

function callIframe(url, callback) {
    $(document.body).append('<IFRAME id="myId" ...>');
    $('iframe#myId').attr('src', url);

    $('iframe#myId').load(function() {
        callback(this);
    });
}

Ao lidar com iframes eu achei bom o suficiente para evento de carregamento de uso em vez de documento pronto evento.

Outras dicas

Usando jQuery 1.3.2 o seguinte trabalhou para mim:

$('iframe').ready(function() {
  $('body', $('iframe').contents()).html('Hello World!');
});

REVISÃO :! Na verdade, o código acima, por vezes, parece que funciona no Firefox, não parece que funciona no Opera.

Em vez disso, implementou uma solução de votação para os meus propósitos. Simplificado para baixo, parece que isso:

$(function() {
  function manipIframe() {
    el = $('body', $('iframe').contents());
    if (el.length != 1) {
      setTimeout(manipIframe, 100);
      return;
    }
    el.html('Hello World!');
  }
  manipIframe();
});

Esta não requer código nos chamados páginas iframe. Todos reside código e executa de quadro pai / janela.

Na iframes eu costumo resolver este problema, colocando um pequeno script para o fim do bloco:

<body>
The content of your IFrame
<script type="text/javascript">
//<![CDATA[
   fireOnReadyEvent();
   parent.IFrameLoaded();
//]]>
</script>
</body>

Este trabalho maior parte do tempo para mim. Às vezes, a solução mais simples e ingênuo é a mais adequada.

A seguir ideia David Murdoch DrJokepu e eu implementada uma versão mais completa. É requer jQuery sobre o pai eo iframe eo iframe para a sua controle.

código iframe:

var iframe = window.frameElement;

if (iframe){
    iframe.contentDocument = document;//normalization: some browsers don't set the contentDocument, only the contentWindow

    var parent = window.parent;
    $(parent.document).ready(function(){//wait for parent to make sure it has jQuery ready
        var parent$ = parent.jQuery;

        parent$(iframe).trigger("iframeloading");

        $(function(){
            parent$(iframe).trigger("iframeready");
        });

        $(window).load(function(){//kind of unnecessary, but here for completion
            parent$(iframe).trigger("iframeloaded");
        });

        $(window).unload(function(e){//not possible to prevent default
            parent$(iframe).trigger("iframeunloaded");
        });

        $(window).on("beforeunload",function(){
            parent$(iframe).trigger("iframebeforeunload");
        });
    });
}

código de teste pai:

$(function(){
    $("iframe").on("iframeloading iframeready iframeloaded iframebeforeunload iframeunloaded", function(e){
        console.log(e.type);
    });
});

encontrou a solução para o problema.

Quando você clica em um link thickbox que abrir um iframe, é inserir um iframe com um id TB_iframeContent.

Em vez de confiar no evento $(document).ready no código iframe, eu só tenho que ligam para o evento de carga do iframe no documento parent:

$('#TB_iframeContent', top.document).load(ApplyGalleria);

Este é o código da iframe, mas se liga a um evento de um controle no documento pai. Ele funciona no Firefox e IE.

Tente este,

<iframe id="testframe" src="about:blank" onload="if (testframe.location.href != 'about:blank') testframe_loaded()"></iframe>

Tudo que você precisa fazer, então, é criar a função JavaScript testframe_loaded ().

Eu estou carregando o PDF com jQuery ajax em cache do navegador. Então eu criar elemento incorporado com dados já em cache do navegador. Eu acho que ele vai trabalhar com iframe também.


var url = "http://example.com/my.pdf";
// show spinner
$.mobile.showPageLoadingMsg('b', note, false);
$.ajax({
    url: url,
    cache: true,
    mimeType: 'application/pdf',
    success: function () {
        // display cached data
        $(scroller).append('<embed type="application/pdf" src="' + url + '" />');
        // hide spinner
        $.mobile.hidePageLoadingMsg();
    }
});

Você tem que definir o seu http cabeçalhos corretamente também.


HttpContext.Response.Expires = 1;
HttpContext.Response.Cache.SetNoServerCaching();
HttpContext.Response.Cache.SetAllowResponseInBrowserHistory(false);
HttpContext.Response.CacheControl = "Private";

Basicamente o que outros já publicado, mas IMHO um pouco mais limpo:

$('<iframe/>', {
    src: 'https://example.com/',
    load: function() {
        alert("loaded")
    }
}).appendTo('body');

Este foi o problema exato Corri para com o nosso cliente. Eu criei um pouco plugin jQuery que parece funcionar para a prontidão iframe. Ele usa pesquisa para verificar o readyState documento iframe combinado com a url documento interno combinado com a fonte iframe para garantir que o iframe é de fato "pronto".

O problema com "onload" é ??que você precisa ter acesso ao iframe real que está sendo adicionado ao DOM, se você não fizer isso, então você precisa para tentar pegar o carregamento iframe que se ele é armazenado em cache, em seguida, você não pode. O que eu precisava era de um script que pode ser chamado a qualquer hora, e determinar se ou não o iframe estava "pronto" ou não.

Aqui está a pergunta:

Santo Graal para determinar se ou não iframe local tem carregado

e aqui está a jsFiddle eu finalmente veio com.

https://jsfiddle.net/q0smjkh5/10/

No jsFiddle acima, eu estou esperando por onload para anexar um iframe para o dom, em seguida, verificar iframe seu estado pronto do documento interno - que deve ser de domínio cruzado, porque ele foi apontado wikipedia - mas Chrome parece denunciar o "completo". O plug-in do método iready fica então chamado quando o iframe é de fato pronto. As tentativas de retorno de chamada para verificar estado de prontidão do documento interno novamente - desta vez relatando um pedido cruz de domínio (que é correto.) - de qualquer maneira parece funcionar para o que eu preciso e espero que ajude outros

<script>
  (function($, document, undefined) {
    $.fn["iready"] = function(callback) {
      var ifr = this.filter("iframe"),
          arg = arguments,
          src = this,
          clc = null, // collection
          lng = 50,   // length of time to wait between intervals
          ivl = -1,   // interval id
          chk = function(ifr) {
            try {
              var cnt = ifr.contents(),
                  doc = cnt[0],
                  src = ifr.attr("src"),
                  url = doc.URL;
              switch (doc.readyState) {
                case "complete":
                  if (!src || src === "about:blank") {
                    // we don't care about empty iframes
                    ifr.data("ready", "true");
                  } else if (!url || url === "about:blank") {
                    // empty document still needs loaded
                    ifr.data("ready", undefined);
                  } else {
                    // not an empty iframe and not an empty src
                    // should be loaded
                    ifr.data("ready", true);
                  }

                  break;
                case "interactive":
                  ifr.data("ready", "true");
                  break;
                case "loading":
                default:
                  // still loading
                  break;   
              }
            } catch (ignore) {
              // as far as we're concerned the iframe is ready
              // since we won't be able to access it cross domain
              ifr.data("ready", "true");
            }

            return ifr.data("ready") === "true";
          };

      if (ifr.length) {
        ifr.each(function() {
          if (!$(this).data("ready")) {
            // add to collection
            clc = (clc) ? clc.add($(this)) : $(this);
          }
        });
        if (clc) {
          ivl = setInterval(function() {
            var rd = true;
            clc.each(function() {
              if (!$(this).data("ready")) {
                if (!chk($(this))) {
                  rd = false;
                }
              }
            });

            if (rd) {
              clearInterval(ivl);
              clc = null;
              callback.apply(src, arg);
            }
          }, lng);
        } else {
          clc = null;
          callback.apply(src, arg);
        }
      } else {
        clc = null;
        callback.apply(this, arguments);
      }
      return this;
    };
  }(jQuery, document));
</script>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top