Frage

Wir sind mit jQuery thickbox , um dynamisch ein iframe angezeigt werden, wenn jemand auf ein Bild klickt. In diesem iframe, verwenden wir galleria eine JavaScript-Bibliothek mehrere Bilder angezeigt werden.

Das Problem scheint, dass $(document).ready im iframe zu sein scheint zu früh entlassen zu werden und der iframe Inhalt noch nicht einmal geladen wird, so galleria Code nicht richtig auf den DOM-Elementen angewandt. $(document).ready scheint die iframe Eltern bereit Zustand zu verwenden, um zu entscheiden, ob die iframe bereit ist.

Wenn wir die Funktion aufgerufen Dokument bereit, in einer separaten Funktion und rufen sie nach einem Timeout von 100 ms extrahieren. Es funktioniert, aber wir können nicht die Chance, in der Produktion mit einem langsamen Computer nehmen.

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

Meine Frage: Welche jQuery Ereignis sollten wir unseren Code zu können, binden auszuführen, wenn der dynamische iframe bereit ist und nicht nur ist es ein Elternteil

War es hilfreich?

Lösung

Ich antwortete eine ähnliche Frage (siehe Javascript Rückruf bei IFRAME Laden fertig ist? ). Sie können mit dem folgenden Code der Kontrolle über das iframe Ladeereignis erhalten:

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

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

Im Umgang mit iframes ich gut genug gefunden Ladeereignis zu verwenden, anstatt von Dokumenten bereit Ereignisse.

Andere Tipps

jQuery 1.3.2 die für mich gearbeitet folgenden:

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

REVISION :! Eigentlich manchmal der obige Code sieht aus wie es in Firefox funktioniert, sieht nie, wie es in Opera funktioniert.

Stattdessen implementiert ich eine Polling-Lösung für meine Zwecke. Vereinfachtes nach unten sieht es wie folgt aus:

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

Dies erfordert keinen Code in den genannten iframe Seiten. Die gesamte Code befindet, und führt aus dem übergeordneten Frame / Fenster.

In IFrames ich in der Regel dieses Problem lösen, indem ein kleines Skript bis zum Ende des Blockes setzen:

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

Diese Arbeit die meiste Zeit für mich. Manchmal ist die einfachste und naive Lösung ist am besten geeignet.

Nach DrJokepu der und David Murdoch Idee, die ich implementiert eine vollständigere Version. Es erfordert jQuery sowohl auf die Eltern und iframe und den iframe in Ihrer Kontrolle.

iframe-Code:

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

Eltern Testcode:

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

, um die Lösung für das Problem gefunden.

Wenn Sie auf einem thickbox Link klicken, der einen iframe öffnen, einen Iframe mit der ID TB_iframeContent einzufügen.

Statt auf dem $(document).ready Ereignisse in dem iframe-Code zu verlassen, ich habe gerade auf das Ladeereignis des iframe im übergeordneten Dokument binden müssen:

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

Dieser Code ist in der iframe aber bindet an ein Ereignis eines Steuerelements im übergeordneten Dokument. Es funktioniert in Firefox und IE.

Versuchen Sie dies,

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

Alles, was Sie dann tun müssen, ist die JavaScript-Funktion testframe_loaded () erstellen.

Ich lade das PDF mit jQuery Ajax in den Browser-Cache. Dann erstelle ich eingebettetes Element mit Daten, die bereits in dem Browser-Cache. Ich denke, es wird auch mit iframe arbeiten.


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

Sie haben Ihre HTTP-Header korrekt als auch setzen.


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

Im Grunde, was andere haben bereits gebucht, aber meiner Meinung nach etwas sauberer:

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

Das war das genaue Problem, das ich mit dem Klienten lief in. Ich habe ein wenig jQuery-Plugin, das für iframe Bereitschaft scheint zu funktionieren. Es verwendet Abfrage des iframe Dokument Readystate mit der inneren Dokument URL mit der iframe Quelle sicher, dass der iframe ist, um in Kombination kombiniert zu überprüfen, in der Tat „bereit“.

Das Problem mit „onload“ ist, dass Sie Zugriff auf die eigentliche iframe müssen den DOM hinzugefügt werden, wenn Sie dies nicht tun, dann müssen Sie versuchen, den iframe Laden zu fangen, die, wenn sie im Cache gespeichert wird, dann können Sie nicht. Was ich brauchte, war ein Skript, das zu jeder Zeit aufgerufen werden könnte, und bestimmen, ob der iframe war „bereit“ ist oder nicht.

Hier ist die Frage:

Heiliger Gral für die Bestimmung, ob oder nicht lokale iframe geladen

und hier ist die jsfiddle ich schließlich kam mit.

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

In der jsfiddle oben, ich bin für onload warte einen iframe auf den dom anhänge, dann iframe inneres Dokuments Bereitschaftszustand überprüft - die Cross-Domain sein sollte, weil es auf wikipedia hingewiesen wird - aber Chrome scheint „vollständig“ zu berichten. Die Plug-In-IREADY Methode dann aufgerufen wird, wenn der iframe in der Tat bereit ist. Der Rückruf versucht, das innere Dokument Bereitschaftszustand wieder zu überprüfen - diesmal eine Cross-Domain-Anfrage Berichterstattung (was richtig ist.) - trotzdem scheint es, dafür zu arbeiten, was ich brauche und hoffe, dass es hilft, andere

<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>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top