سؤال

نحن نستخدم مسج صندوق سميك لعرض إطار iframe ديناميكيًا عندما ينقر شخص ما على الصورة.في هذا iframe، نحن نستخدم جاليريا مكتبة جافا سكريبت لعرض صور متعددة.

يبدو أن المشكلة هي ذلك $(document).ready في iframe يبدو أنه تم إطلاقه مبكرًا جدًا ولم يتم تحميل محتوى iframe حتى الآن، لذلك لا يتم تطبيق كود Galleria بشكل صحيح على عناصر DOM. $(document).ready يبدو أنه يستخدم حالة الاستعداد الأصلية لـ iframe لتحديد ما إذا كان iframe جاهزًا أم لا.

إذا استخرجنا الوظيفة التي يطلق عليها المستند جاهزة في وظيفة منفصلة واستدعيناها بعد مهلة قدرها 100 مللي ثانية.إنه يعمل، لكن لا يمكننا استغلال الفرصة في الإنتاج باستخدام جهاز كمبيوتر بطيء.

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

سؤالي:ما هو حدث jQuery الذي يجب أن نلتزم به حتى نتمكن من تنفيذ التعليمات البرمجية الخاصة بنا عندما يكون إطار iframe الديناميكي جاهزًا وليس فقط أحد الوالدين؟

هل كانت مفيدة؟

المحلول

ولقد أجبت على سؤال مماثل (انظر جافا سكريبت الاستدعاء عندما يتم الانتهاء من IFRAME تحميل؟ ). يمكنك الحصول على السيطرة على الحدث تحميل IFRAME مع التعليمات البرمجية التالية:

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

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

في التعامل مع نوافذ الأطر المدمجة وجدت جيدة بما فيه الكفاية لاستخدام الحدث تحميل بدلا من وثيقة حالة استعداد.

نصائح أخرى

وعن طريق مسج 1.3.2 ما يلي عملت بالنسبة لي:

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

وREVISION:! في الواقع رمز أعلاه تبدو أحيانا وكأنها تعمل في فايرفوكس، لا يبدو أنه يعمل في الأوبرا.

وبدلا من ذلك وتنفيذ حل الاقتراع لأغراض بلدي. المبسطة أسفل يبدو مثل هذا:

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

وهذا لا يتطلب التعليمات البرمجية في تسمى صفحات IFRAME. كل رمز موجود وينفذ من الإطار الأصل / نافذة.

في إطارات IFrame وعادة ما حل هذه المشكلة عن طريق وضع نصي صغير حتى النهاية من كتلة:

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

وهذا العمل معظم الوقت بالنسبة لي. أحيانا الحل الأبسط والأكثر ساذج هو الأنسب.

بعد فكرة DrJokepu وDavid Murdoch، قمت بتنفيذ نسخة أكثر اكتمالاً.هو - هي يتطلب jQuery على كل من الأصل وiframe وiframe ليكون تحت سيطرتك.

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

رمز اختبار الوالدين:

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

وجدت الحل لهذه المشكلة.

عند النقر على رابط thickbox أن فتح iframe على ذلك إدراج إطار iframe مع معرف TB_iframeContent.

وبدلا من الاعتماد على الحدث $(document).ready في كود iframe، أنا فقط يجب أن ربط الحدث تحميل من إطار iframe في الوثيقة الأصلية:

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

وهذا الرمز هو في إطار iframe لكن بربط حدث لعنصر تحكم في الوثيقة الأصلية. وهو يعمل في فايرفوكس وإنترنت إكسبلورر.

وجرب هذا،

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

وكل ما عليك القيام به بعد ذلك هو خلق وظيفة جافا سكريبت testframe_loaded ().

وأنا تحميل PDF مع مسج اياكس في مخبأ المتصفح. ثم أنا خلق عنصر جزءا لا يتجزأ مع البيانات بالفعل في مخبأ المتصفح. اعتقد انها ستعمل مع IFRAME جدا.


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

ولديك لتعيين عناوين http بشكل صحيح أيضا.


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

وأساسا ما الآخرين وقد نشرت بالفعل ولكن IMHO قليلا نظافة:

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

وكانت هذه هي القضية بالضبط جريت إلى مع عملائنا. أنا خلقت المساعد مسج الصغير الذي يبدو للعمل من أجل الاستعداد IFRAME. ويستخدم الاقتراع للتحقق في ReadyState ثيقة الإطار من جنبا إلى جنب مع رابط ثيقة الداخلي جنبا إلى جنب مع مصدر iframe للتأكد من أن الإطار من هو في الواقع "جاهزة".

وهذه المسألة مع "ONLOAD" هي التي تحتاج إلى الوصول إلى إطار iframe الفعلي إضافتها إلى DOM، إذا لم تقم بذلك فإنك تحتاج إلى محاولة للقبض على تحميل IFRAME التي إذا تم تخزينها مؤقتا بعد ذلك لا يجوز لك. ما يلزم هو السيناريو الذي يمكن أن يسمى أي وقت، وتحديد ما إذا كان الإطار من "مستعدة" أم لا.

وهنا يكمن السؤال:

الكأس المقدسة لتحديد ما إذا كان أو لا الإطار من المحليين وتحميل

وهنا تكمن jsfiddle جئت في نهاية المطاف مع.

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

في لjsfiddle أعلاه، وأنا في انتظار ONLOAD إلحاق iframe للدوم، ثم فحص حالة استعداد وثيقة داخلية في الإطار من - والتي يجب أن تكون عبر نطاق لأنه أشار إلى ويكيبيديا - ولكن يبدو كروم أن يقدم "كاملة". طريقة iready المكونات في لثم يحصل على استدعاء عندما إطار iframe هو في الواقع جاهزة. يحاول رد للتحقق من حالة استعداد وثيقة الداخلية مرة أخرى - وهذه المرة الإبلاغ عن طلب عبر المجال (وهو الصحيح) - على أي حال يبدو للعمل من أجل ما أحتاج وآمل أن يساعد الآخرين

<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>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top