[javascript] 동적으로 삽입 된 iframe의 jQuery .ready

우리는 누군가가 그림을 클릭 할 때 jQuery thickbox 를 사용하여 iframe을 동적으로 표시합니다. 이 iframe에서는 여러 그림을 표시하기 위해 갤러리아 를 자바 스크립트 라이브러리로 사용 하고 있습니다.

문제 $(document).ready는 iframe에서 너무 빨리 실행되고 iframe 내용이 아직로드되지 않아서 갤러리 요소가 DOM 요소에 제대로 적용되지 않는 것 같습니다. $(document).readyiframe이 준비되었는지 여부를 결정하기 위해 iframe 상위 준비 상태를 사용하는 것 같습니다.

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

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

내 질문 : 동적 iframe이 준비되어 있고 부모 일뿐 만 아니라 코드를 실행할 수 있도록 바인딩해야 할 jQuery 이벤트는 무엇입니까?



답변

비슷한 질문에 답했습니다 ( IFRAME 이로 드가 완료되면 Javascript 콜백 참조 ). 다음 코드를 사용하여 iframe로드 이벤트를 제어 할 수 있습니다.

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

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

iframe을 다룰 때 문서 준비 이벤트 대신로드 이벤트를 사용하기에 충분하다는 것을 알았습니다.


답변

jQuery 1.3.2를 사용하면 다음이 효과적이었습니다.

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

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

대신 내 목적을 위해 폴링 솔루션을 구현했습니다. 단순화 된 모양은 다음과 같습니다.

$(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을 여는 thickbox 링크를 클릭하면 ID가 TB_iframeContent 인 iframe이 삽입됩니다.

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

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

이 코드는 iframe에 있지만 부모 문서의 컨트롤 이벤트에 바인딩됩니다. FireFox 및 IE에서 작동합니다.


답변

기본적으로 다른 사람들이 이미 게시했지만 IMHO는 약간 깨끗합니다.

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


답변

이 시도,

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

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