Calling javascript function in iframe

JavascriptFunctionIframe

Javascript Problem Overview


I have problem calling a JavaScript function in an iframe from the parent page. Here is my two pages:

mainPage.html

<html>
<head>
	<title>MainPage</title>
	<script type="text/javascript">
		function Reset() 
		{
			if (document.all.resultFrame)
				alert("resultFrame found");
			else
				alert("resultFrame NOT found");

			if (typeof (document.all.resultFrame.Reset) == "function")
				document.all.resultFrame.Reset();
			else
				alert("resultFrame.Reset NOT found");
		}
	</script>
</head>
<body>
	MainPage<br>
	<input type="button" onclick="Reset()" value="Reset"><br><br>
	<iframe height="100" id="resultFrame" src="resultFrame.html"></iframe>
</body>
</html>

resultFrame.html

<html>
<head>
	<title>ResultPage</title>
	<script type="text/javascript">
		function Reset() 
		{
			alert("reset (in resultframe)");
		}
	</script>
</head>
<body>
	ResultPage
</body>
</html>

(I know that document.all isn't recommended but this page should only be viewed with IE internally and I don't think that's the problem)

When I press the Reset-button I get "resultFrame found" and "resultFrame.Reset NOT found". It seems to have a reference to the frame but can't call the function on the frame, why is that?

Javascript Solutions


Solution 1 - Javascript

Use:

document.getElementById("resultFrame").contentWindow.Reset();

to access the Reset function in the iframe

document.getElementById("resultFrame") will get the iframe in your code, and contentWindow will get the window object in the iframe. Once you have the child window, you can refer to javascript in that context.

Also see HERE in particular the answer from bobince.

Solution 2 - Javascript

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

Solution 3 - Javascript

Instead of getting the frame from the document, try getting the frame from the window object.

in the above example change this:

if (typeof (document.all.resultFrame.Reset) == "function")
    document.all.resultFrame.Reset();
else
    alert("resultFrame.Reset NOT found");

to

if (typeof (window.frames[0].Reset) == "function")
    window.frames[0].Reset();
else
    alert("resultFrame.Reset NOT found");

the problem is that the scope of the javascript inside the iframe is not exposed through the DOM element for the iframe. only window objects contain the javascript scoping information for the frames.

Solution 4 - Javascript

Call

window.frames['resultFrame'].Reset();

Solution 5 - Javascript

objectframe.contentWindow.Reset() you need reference to the top level element in the frame first.

Solution 6 - Javascript

The first and foremost condition that needs to be met is that both the parent and iframe should belong to the same origin. Once that is done the child can invoke the parent using window.opener method and the parent can do the same for the child as mentioned above

Solution 7 - Javascript

When you access resultFrame through document.all it only pulls it as an HTML element, not a window frame. You get the same issue if you have a frame fire an event using a "this" self-reference.

Replace:

document.all.resultFrame.Reset();

With:

window.frames.resultFrame.Reset();

Or:

document.all.resultFrame.contentWindow.Reset();

Solution 8 - Javascript

If you can not use it directly and if you encounter this error: Blocked a frame with origin "http://www.<domain>.com" from accessing a cross-origin frame. You can use postMessage() instead of using the function directly.

Solution 9 - Javascript

Calling a privacy-respecting XMLHttpRequest from an <iframe>

HTML:

<iframe id="iframe"></iframe>

JavaScript:

const iframe    = document.getElementById('iframe');
const iframeWin = iframe.contentWindow || iframe;
const iframeDoc = iframe.contentDocument || iframeWin.document;

let script = iframeDoc.createElement('SCRIPT');

script.append(`function sendWithoutOrigin(url) {
    let request = new XMLHttpRequest();

    request.open('GET', url);

    request.onreadystatechange = function() {
        if(request.readyState === XMLHttpRequest.DONE) {
            if(request.status === 200) {
                console.log('GET succeeded.');
            }
            else {
                console.warn('GET failed.');
            }
        }
    }
    request.send();
}`);

iframeDoc.documentElement.appendChild(script);

JavaScript evocation:

let url  = 'https://api.serivce.net/';
    url += '?api_key=' + api_write_key;
    url += '&field1=' + value;

iframeWin.sendWithoutOrigin(url);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionsalle55View Question on Stackoverflow
Solution 1 - JavascriptJonathan FinglandView Answer on Stackoverflow
Solution 2 - JavascriptDominique FortinView Answer on Stackoverflow
Solution 3 - JavascriptbarkmadleyView Answer on Stackoverflow
Solution 4 - JavascriptArsen MkrtchyanView Answer on Stackoverflow
Solution 5 - JavascriptAlex HView Answer on Stackoverflow
Solution 6 - JavascriptRavi BhagavatulaView Answer on Stackoverflow
Solution 7 - JavascriptCoding With StyleView Answer on Stackoverflow
Solution 8 - Javascriptuser9384187View Answer on Stackoverflow
Solution 9 - JavascriptSerge StroobandtView Answer on Stackoverflow