동적으로 삽입 된 iframe의 jQuery .ready
우리는 누군가가 그림을 클릭 할 때 jQuery thickbox 를 사용하여 iframe을 동적으로 표시합니다. 이 iframe에서는 여러 그림을 표시하기 위해 갤러리아 를 자바 스크립트 라이브러리로 사용 하고 있습니다.
문제 $(document).ready
는 iframe에서 너무 빨리 실행되고 iframe 내용이 아직로드되지 않아서 갤러리 요소가 DOM 요소에 제대로 적용되지 않는 것 같습니다. $(document).ready
iframe이 준비되었는지 여부를 결정하기 위해 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).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>
All you need to do then is create the JavaScript function testframe_loaded().
I'm loading the PDF with jQuery ajax into browser cache. Then I create embedded element with data already in browser cache. I guess it will work with iframe too.
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();
}
});
You have to set your http headers correctly as well.
HttpContext.Response.Expires = 1;
HttpContext.Response.Cache.SetNoServerCaching();
HttpContext.Response.Cache.SetAllowResponseInBrowserHistory(false);
HttpContext.Response.CacheControl = "Private";
This was the exact issue I ran into with our client. I created a little jquery plugin that seems to work for iframe readiness. It uses polling to check the iframe document readyState combined with the inner document url combined with the iframe source to make sure the iframe is in fact "ready".
The issue with "onload" is that you need access to the actual iframe being added to the DOM, if you don't then you need to try to catch the iframe loading which if it is cached then you may not. What I needed was a script that could be called anytime, and determine whether or not the iframe was "ready" or not.
Here's the question:
Holy grail for determining whether or not local iframe has loaded
and here's the jsfiddle I eventually came up with.
https://jsfiddle.net/q0smjkh5/10/
In the jsfiddle above, I am waiting for onload to append an iframe to the dom, then checking iframe's inner document's ready state - which should be cross domain because it's pointed to wikipedia - but Chrome seems to report "complete". The plug-in's iready method then gets called when the iframe is in fact ready. The callback tries to check the inner document's ready state again - this time reporting a cross domain request (which is correct) - anyway it seems to work for what I need and hope it helps others.
<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>
Basically what others have already posted but IMHO a bit cleaner:
$('<iframe/>', {
src: 'https://example.com/',
load: function() {
alert("loaded")
}
}).appendTo('body');
참고URL : https://stackoverflow.com/questions/205087/jquery-ready-in-a-dynamically-inserted-iframe
'Programing' 카테고리의 다른 글
Tornado 사용시기, Twisted / Cyclone / GEvent / 기타 사용시기 (0) | 2020.05.19 |
---|---|
Perl에서 나와 우리의 차이점은 무엇입니까? (0) | 2020.05.19 |
파일 이름이 포함 된 경로에서 파일 이름없이 전체 경로 가져 오기 (0) | 2020.05.19 |
매크로에서 익명 클래스의 메소드를 사용하여 구조 유형 가져 오기 (0) | 2020.05.18 |
Android에서 가로 ListView를 만들려면 어떻게해야합니까? (0) | 2020.05.18 |