문제

우리는 jQuery를 사용하고 있습니다 두꺼운 상자 누군가 사진을 클릭 할 때 iframe을 동적으로 표시하려면. 이 Iframe에서 우리는 사용 중입니다 갤러리아 여러 사진을 표시하는 JavaScript 라이브러리.

문제는 그 것 같습니다 $(document).ready Iframe에서는 너무 빨리 해고 된 것으로 보이며 Iframe 컨텐츠는 아직로드되지 않았으므로 Galleria 코드는 DOM 요소에 제대로 적용되지 않습니다. $(document).ready Iframe Parent Ready State를 사용하여 Iframe이 준비되었는지 여부를 결정하는 것 같습니다.

별도의 기능으로 준비된 문서별로 호출 된 함수를 추출하고 100ms의 시간 초과 후 호출하십시오. 작동하지만 느린 컴퓨터로 생산에 기회를 잡을 수는 없습니다.

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

내 질문 : Dynamic Iframe이 준비되었을 때 코드를 실행할 수 있도록 어떤 jQuery 이벤트를 구속해야합니까?

도움이 되었습니까?

해결책

나는 비슷한 질문에 대답했다 (참조 JavaScript 콜백 Iframe이로드가 완료되었을 때?). 다음 코드로 iframe로드 이벤트를 제어 할 수 있습니다.

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

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

iframes를 다루면서 문서 준비 이벤트 대신로드 이벤트를 사용하기에 충분히 좋았습니다.

다른 팁

jQuery 1.3.2 사용 다음은 저에게 효과적이었습니다.

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

개정:! 실제로 위의 코드는 때때로 Firefox에서 작동하는 것처럼 보이며 오페라에서 작동하는 것처럼 보이지 않습니다.

대신 나는 나의 목적을위한 폴링 솔루션을 구현했다. 단순화 : 다음과 같이 보입니다.

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

호출 iframe 페이지에서 코드가 필요하지 않습니다. 모든 코드는 상위 프레임/창에서 존재하고 실행됩니다.

iframes에서 나는 보통 블록의 끝에 작은 스크립트를 넣어이 문제를 해결합니다.

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

이것은 나를 위해 대부분의 일을합니다. 때로는 가장 단순하고 순진한 솔루션이 가장 적합합니다.

Drjokepu와 David Murdoch 아이디어에 따라 나는 더 완전한 버전을 구현했습니다. 그것 필요합니다 부모와 iframe과 iframe 모두에 대한 jQuery가 귀하의 통제에 참여할 수 있습니다.

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

문제에 대한 해결책을 찾았습니다.

iframe을 열 수있는 두꺼운 박스 링크를 클릭하면 tb_iframecontent의 ID와 함께 iframe을 삽입합니다.

에 의존하는 대신 $(document).ready 이벤트 iframe 코드에서는 부모 문서에서 iframe의로드 이벤트에 바인딩해야합니다.

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

이 코드는 iframe에 있지만 상위 문서의 컨트롤 이벤트에 바인딩됩니다. Firefox와 IE에서 작동합니다.

이 시도,

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

그러면 JavaScript 함수 testframe_loaded ()를 작성하기 만하면됩니다.

jQuery ajax와 함께 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";

기본적으로 다른 사람들이 이미 게시 한 내용이지만 조금 더 깨끗합니다.

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

이것은 내가 고객과 함께한 정확한 문제였습니다. iframe 준비에 맞는 것처럼 보이는 작은 jQuery 플러그인을 만들었습니다. 폴링을 사용하여 iframe 소스와 결합 된 내부 문서 URL과 결합 된 iframe 문서 Readystate를 확인하여 iframe이 실제로 "준비"되어 있는지 확인합니다.

"Onload"의 문제는 DOM에 추가되는 실제 iframe에 액세스해야한다는 것입니다. 그렇지 않으면 iframe로드를 잡아야한다면 캐시 된 경우 그렇지 않을 수도 있습니다. 내가 필요로하는 것은 언제든지 전화 할 수있는 대본이었고, iframe이 "준비된 것"인지 아닌지를 결정했습니다.

질문은 다음과 같습니다.

현지 Iframe이로드되었는지 여부를 결정한 거룩한 성배

그리고 여기 내가 결국 내가 생각한 JSFIDDE가 있습니다.

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

위의 jsfiddle에서, 나는 onload가 dom에 iframe을 추가하기를 기다린 다음 iframe의 내부 문서의 준비 상태를 확인하고 있습니다. 이것은 위키 백과를 가리키기 때문에 크로스 도메인이어야합니다. 그러나 Chrome은 "완전한"보고서를보고하는 것 같습니다. 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