상위 페이지의 iframe에서 JavaScript 코드 호출
기본적으로, 나는 한 iframe
페이지에 포함하고는 iframe
몇 가지가 자바 스크립트 내가 부모 페이지에서 호출 할 필요가 루틴을.
이제는을 호출하기 만하면되므로 그 반대는 매우 간단합니다 parent.functionName()
.하지만 안타깝게도 그 반대가 필요합니다.
내 문제는 소스 변경되지 않도록 유의하시기 바랍니다 URL 의를 iframe
, 그러나에 정의 된 함수를 호출 iframe
.
iFrame의 ID가 "targetFrame"이고 호출하려는 함수가 다음과 같다고 가정합니다 targetFunction()
.
document.getElementById('targetFrame').contentWindow.targetFunction();
window.frames
대신을 사용하여 프레임에 액세스 할 수도 있습니다 document.getElementById
.
// this option does not work in most of latest versions of chrome and Firefox
window.frames[0].frameElement.contentWindow.targetFunction();
여기에서 알아야 할 몇 가지 단점이 있습니다.
HTMLIFrameElement.contentWindow
아마도 더 쉬운 방법 일 수 있지만 표준 속성이 아니며 일부 브라우저는이를 지원하지 않습니다. 대부분 오래된 브라우저입니다. 이는 DOM 레벨 1 HTML 표준이window
객체 에 대해 말할 것이 없기 때문 입니다.HTMLIFrameElement.contentDocument.defaultView
몇 가지 이전 브라우저에서는 허용하지만 IE에서는 허용하지 않는을 사용해 볼 수도 있습니다 . 그럼에도 불구하고 표준은window
(1)과 같은 이유로 객체를 되 찾는다고 명시 적으로 말하지 않지만, 관심이 있다면 여기에서 몇 가지 추가 브라우저 버전을 선택할 수 있습니다.window.frames['name']
창을 반환하는 것은 가장 오래되고 따라서 가장 안정적인 인터페이스입니다. 그러나 그런 다음name="..."
이름으로 프레임을 가져올 수 있는 속성 을 사용해야합니다 . 이는 약간 못생긴 /더 이상 사용되지 않는/ transitional입니다. (id="..."
더 좋을 것이지만 IE는 그것을 좋아하지 않습니다.)window.frames[number]
또한 매우 신뢰할 수 있지만 올바른 인덱스를 아는 것이 트릭입니다. 예를 들어 이것으로 벗어날 수 있습니다. 페이지에 iframe이 하나만 있다는 것을 알고 있다면.하위 iframe이 아직로드되지 않았거나 액세스 할 수 없도록 다른 문제가 발생했을 수 있습니다. 통신 흐름을 역전시키는 것이 더 쉬울 수 있습니다. 즉,
window.parent
로드가 완료되고 콜백 할 준비가되면 하위 iframe이 스크립트에 알리도록합니다 . 부모 스크립트에 자체 개체 (예 : 콜백 함수) 중 하나를 전달하면 해당 부모는 연결된 HTMLIFrameElement에 대해 걱정할 필요없이 iframe의 스크립트와 직접 통신 할 수 있습니다.
에서 부모 JS 함수를 호출하는 iframe
것은 가능하지만 부모와에로드 된 페이지가 모두 iframe
동일한 도메인 (예 : abc.com)에 있고 둘 다 동일한 프로토콜을 사용하는 경우 (예 : 둘 다 on http://
또는) 인 경우에만 가능 https://
합니다.
아래 언급 된 경우에는 호출이 실패합니다.
- 상위 페이지와 iframe 페이지가 다른 도메인에 있습니다.
- 그들은 다른 프로토콜을 사용하고 있습니다. 하나는 http : //에 있고 다른 하나는 https : //에 있습니다.
이 제한에 대한 해결 방법은 매우 안전하지 않습니다.
예를 들어, 내가 superwinningcontest.com 도메인을 등록하고 사람들의 이메일에 대한 링크를 보냈다고 상상해보십시오. 그들이 메인 페이지를로드했을 때, 나는 iframe
거기에 몇 개의 s를 숨기고 그들의 Facebook 피드를 읽거나, 최근의 Amazon 또는 PayPal 거래를 확인하거나, 충분한 보안을 구현하지 않는 서비스를 사용한 경우 자금을 다른 곳으로 이체 할 수 있습니다. 계정. 이것이 자바 스크립트가 동일한 도메인과 동일한 프로토콜로 제한되는 이유입니다.
IFRAME에서 함수를 창 개체에 공개합니다.
window.myFunction = function(args) {
doStuff();
}
상위 페이지에서 액세스하려면 다음을 사용하십시오.
var iframe = document.getElementById("iframeId");
iframe.contentWindow.myFunction(args);
iFrame과 포함 된 문서가 다른 도메인에있는 경우 이전에 게시 된 방법이 작동하지 않을 수 있지만 해결책이 있습니다.
예를 들어, 문서 A에 문서 B가 포함 된 iframe 요소가 포함되어 있고 문서 A의 스크립트가 문서 B의 Window 개체에 대해 postMessage ()를 호출하면 해당 개체에서 메시지 이벤트가 발생하여 해당 개체에서 시작된 것으로 표시됩니다. 문서 A. 문서 A의 스크립트는 다음과 같습니다.
var o = document.getElementsByTagName('iframe')[0];
o.contentWindow.postMessage('Hello world', 'http://b.example.org/');
들어오는 이벤트에 대한 이벤트 핸들러를 등록하기 위해 스크립트는 addEventListener () (또는 유사한 메커니즘)를 사용합니다. 예를 들어 문서 B의 스크립트는 다음과 같습니다.
window.addEventListener('message', receiver, false);
function receiver(e) {
if (e.origin == 'http://example.com') {
if (e.data == 'Hello world') {
e.source.postMessage('Hello', e.origin);
} else {
alert(e.data);
}
}
}
이 스크립트는 먼저 도메인이 예상 도메인인지 확인한 다음 사용자에게 표시하거나 처음에 메시지를 보낸 문서로 메시지를 다시 보내 응답하는 메시지를 확인합니다.
http://dev.w3.org/html5/postmsg/#web-messaging을 통해
기록을 위해 오늘도 같은 문제가 발생했지만 이번에는 페이지가 iframe이 아닌 개체에 포함되었습니다 (XHTML 1.1 문서이기 때문에). 다음은 개체와 함께 작동하는 방법입니다.
document
.getElementById('targetFrame')
.contentDocument
.defaultView
.targetFunction();
(못생긴 줄 바꿈에 대해 죄송합니다. 한 줄에 맞지 않았습니다)
IFRAME은 frames[]
컬렉션에 있어야합니다 . 다음과 같은 것을 사용하십시오.
frames['iframeid'].method();
Quirksmode는 이것에 대한 게시물을 가지고 있습니다.
이제 페이지가 깨져서 archive.org를 통해서만 액세스 할 수 있으므로 여기에서 재현했습니다.
IFrame
이 페이지에서는 해당 페이지에서 iframe에 액세스하는 방법에 대한 간략한 개요를 제공합니다. 당연히 몇 가지 브라우저 고려 사항이 있습니다.
An iframe is an inline frame, a frame that, while containing a completely separate page with its own URL, is nonetheless placed inside another HTML page. This gives very nice possibilities in web design. The problem is to access the iframe, for instance to load a new page into it. This page explains how to do it.
Frame or object?
The fundamental question is whether the iframe is seen as a frame or as an object.
- As explained on the Introduction to frames pages, if you use frames the browser creates a frame hierarchy for you (
top.frames[1].frames[2]
and such). Does the iframe fit into this frame hierarchy? - Or does the browser see an iframe as just another object, an object that happens to have a src property? In that case we have to use a standard DOM call (like
document.getElementById('theiframe'))
to access it. In general browsers allow both views on 'real' (hard-coded) iframes, but generated iframes cannot be accessed as frames.
NAME attribute
The most important rule is to give any iframe you create a name
attribute, even if you also use an id
.
<iframe src="iframe_page1.html"
id="testiframe"
name="testiframe"></iframe>
Most browsers need the name
attribute to make the iframe part of the frame hierarchy. Some browsers (notably Mozilla) need the id
to make the iframe accessible as an object. By assigning both attributes to the iframe you keep your options open. But name
is far more important than id
.
Access
Either you access the iframe as an object and change its src
or you access the iframe as a frame and change its location.href
.
document.getElementById('iframe_id').src = 'newpage.html'; frames['iframe_name'].location.href = 'newpage.html'; The frame syntax is slightly preferable because Opera 6 supports it but not the object syntax.
Accessing the iframe
So for a complete cross–browser experience you should give the iframe a name and use the
frames['testiframe'].location.href
syntax. As far as I know this always works.
Accessing the document
Accessing the document inside the iframe is quite simple, provided you use the name
attribute. To count the number of links in the document in the iframe, do frames['testiframe'].document.links.length
.
Generated iframes
When you generate an iframe through the W3C DOM the iframe is not immediately entered into the frames
array, though, and the frames['testiframe'].location.href
syntax will not work right away. The browser needs a little time before the iframe turns up in the array, time during which no script may run.
The document.getElementById('testiframe').src
syntax works fine in all circumstances.
The target
attribute of a link doesn't work either with generated iframes, except in Opera, even though I gave my generated iframe both a name
and an id
.
The lack of target
support means that you must use JavaScript to change the content of a generated iframe, but since you need JavaScript anyway to generate it in the first place, I don't see this as much of a problem.
Text size in iframes
A curious Explorer 6 only bug:
When you change the text size through the View menu, text sizes in iframes are correctly changed. However, this browser does not change the line breaks in the original text, so that part of the text may become invisible, or line breaks may occur while the line could still hold another word.
I found quite an elegant solution.
As you said, it's fairly easy to execute code located on the parent document. And that's the base of my code, do to just the opposite.
When my iframe loads, I call a function located on the parent document, passing as an argument a reference to a local function, located in the iframe's document. The parent document now has a direct access to the iframe's function thru this reference.
Example:
On the parent:
function tunnel(fn) {
fn();
}
On the iframe:
var myFunction = function() {
alert("This work!");
}
parent.tunnel(myFunction);
When the iframe loads, it will call parent.tunnel(YourFunctionReference), which will execute the function received in parameter.
That simple, without having to deal with the all the non-standards methods from the various browsers.
Some of these answers don't address the CORS issue, or don't make it obvious where you place the code snippets to make the communication possible.
Here is a concrete example. Say I want to click a button on the parent page, and have that do something inside the iframe. Here is how I would do it.
parent_frame.html
<button id='parent_page_button' onclick='call_button_inside_frame()'></button>
function call_button_inside_frame() {
document.getElementById('my_iframe').contentWindow.postMessage('foo','*');
}
iframe_page.html
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
if(event) {
click_button_inside_frame();
}
}
function click_button_inside_frame() {
document.getElementById('frame_button').click();
}
To go the other direction (click button inside iframe to call method outside iframe) just switch where the code snippet live, and change this:
document.getElementById('my_iframe').contentWindow.postMessage('foo','*');
to this:
window.parent.postMessage('foo','*')
Continuing with JoelAnair's answer:
For more robustness, use as follows:
var el = document.getElementById('targetFrame');
if(el.contentWindow)
{
el.contentWindow.targetFunction();
}
else if(el.contentDocument)
{
el.contentDocument.targetFunction();
}
Workd like charm :)
Folowing Nitin Bansal's answer
and for even more robustness:
function getIframeWindow(iframe_object) {
var doc;
if (iframe_object.contentWindow) {
return iframe_object.contentWindow;
}
if (iframe_object.window) {
return iframe_object.window;
}
if (!doc && iframe_object.contentDocument) {
doc = iframe_object.contentDocument;
}
if (!doc && iframe_object.document) {
doc = iframe_object.document;
}
if (doc && doc.defaultView) {
return doc.defaultView;
}
if (doc && doc.parentWindow) {
return doc.parentWindow;
}
return undefined;
}
and
...
var el = document.getElementById('targetFrame');
var frame_win = getIframeWindow(el);
if (frame_win) {
frame_win.targetFunction();
...
}
...
$("#myframe").load(function() {
alert("loaded");
});
Same things but a bit easier way will be How to refresh parent page from page within iframe. Just call the parent page's function to invoke javascript function to reload the page:
window.location.reload();
Or do this directly from the page in iframe:
window.parent.location.reload();
Both works.
Try just parent.myfunction()
If you want to invoke the JavaScript function on the Parent from the iframe generated by another function ex shadowbox or lightbox.
You should try to make use of window
object and invoke parent function:
window.parent.targetFunction();
Use following to call function of a frame in parent page
parent.document.getElementById('frameid').contentWindow.somefunction()
'Programing' 카테고리의 다른 글
Java에서 YYYY-MM-DD HH : MI : Sec.Millisecond 형식으로 현재 시간을 얻는 방법은 무엇입니까? (0) | 2020.10.03 |
---|---|
확인없이 cp를 강제로 덮어 쓰는 방법 (0) | 2020.10.03 |
Akka의 좋은 사용 사례 [종료 됨] (0) | 2020.10.03 |
지원되지 않는 major.minor 버전 52.0 (0) | 2020.10.03 |
사용자의 시간대 결정 (0) | 2020.10.03 |