How to call javascript function inside an adjacent iframe - javascript

I have an html page where I have this layout essentially:
<html>
<body>
<!-- iFrame A -->
<iframe></iframe>
<!-- iFrame B -->
<iframe></iframe>
</body>
</html>
In IFRAME "B", I'd like to call a js function in IFRAME "A", which will ultimately change the window.location property and redirect the page. I have jquery at my disposal as well, but have been unable to figure out a way of calling something in that adjacent frame.
Any suggestions?

Assuming everything is on the same domain, and you have two iframes with ids "iframe-a" and "iframe-b", with jQuery in the parent:
In frame A:
function foo() {
alert("foo from frame A");
}
From frame b:
window.parent.$("#iframe-a")[0].contentWindow.foo();
And you should see "foo from frame A" get alerted.

In some browsers, the window.frames array is only populated if the frames are named, rather than having only an ID
If the frames are named and the content are from the same origin (domain, port, protocol), then
window.frameb.functionName() will trigger the function in standard javascript. See other answer(s) for jQuery version

Use window.parent to get the parent (the main window) then use window.frames on the parent window to get frame B. From there call your function.

Related

Get the "outest" window object in html document

If I have a document with for example 2 or more Iframes in each other, how can I access the main document's window object from the last one down the tree?
<html>
...
<iframe>
<iframe>
<!-- I'm here -->
</iframe>
</iframe>
...
I want to be able to redirect the browser window to another page but I cant seem to find a way to grab it's window object.
I tried something like
var outest = window;
if(outest.parent){
outest = outest.parent
}
But for some reason it appears that window has infinite parents. Any ideas?
top refers to the outmost window object, i.e. the browser window.

jquery selector from iframe content to object content

I need the following:
I got a html document, in which I have an iframe and an object. Both, the iframe and the object contain separat html files.
Now I want to click a link in the iframe, and this should affect the links inside the object to hide.
How do I use jQuery selectors to select the links in the object html file?
Structure:
<html file parent>
<iframe> html site 1 with link to click</iframe>
<object> html site 2 with links to affect </object>
<html file parent>
Thanks in advance!
This is not possible if the domain of the iframe is different from that of your .
This is a javascript restriction.
For this to possible you need to have control on the url loaded in the iframe.
If it is of same domain then you can probably do that.
If you have control over the iframe's url try this.
First, have a look at window.postMessage. Using this, you may send an event from your iframe to the window parent target. Listening for that event in the window parent (when something in your iframe changed), you will then be able to access any element inside the object tag using a syntax like this:
$('object').contents().find('linkSelector')
Give your iframe an id, let's say myIframe:
<iframe id="myIframe"> html site 1 with link to click</iframe>
Get a reference to the iframe:
var myIframe = document.getElementById('myIframe');
Post a message from iframe:
myIframe.contentWindow.postMessage('iframe.clicked', 'http://your-domain.here.com');
Handler for iframe change:
var handleIframeChange = function(e) {
//
if(e.origin == 'http://your-domain.here.com') {
// Get reference to your `object` tag
var objContent = $('object').contents();
// For instance, let's hide an element with a class of `link-class-here`
objContent.find('.link-class-here').hide();
}
}
Listen on parent window for the event sent by the iframe:
window.addEventListener('iframe.clicked', handleIframeChange, false);
Haven't tested it right now (did this in the past, when I had control over iframe) but it should work, but as I said, only if you can have control over the iframe.

Reloading iframe from separate iframe

I have checked all the reload iframe from another iframe posts on stackoverflow...and I have tried all their solutions but it doesn't seem to help me! So my problem is that I have two iframes on the same page. The iframe's sources are php files that interact with each other, however I need the iframes to reload that way the changes are shown. I have tried many different ways (which I will list below). These iframes are from the same domain. Maybe it is something else that is messing this up? Thanks in advance.
Different statements called from inside one iframe:
parent.document.getElementById(id).src = parent.document.getElementById(id).src;
parent.getElementById(id).location.reload();
Trying to call a parent function that works in the parent window:
Inside iframe -
parent.refresh(id);
Parent window working function -
function refresh(id) {
document.getElementById(id).src = document.getElementById(id).src;
}
If you assign name to iframe most browsers will let you access the iframe's window object via the name value. This is different from referring to an iframe by its id property which will give you a reference to the iframe element itself (from its owner document), and not the iframe's content window.
Simple Example: (from the parent document)
<iframe name='iframe1Name' id='iframe1Id'></iframe>
<script>
// option 1: get a reference to the iframe element:
var iframeElem = document.getElementById('iframe1Id');
// update the element's src:
iframeElem.src = "page.html";
// option 2: get a reference to the iframe's window object:
var iframeWindow = window.iframe1Name;
// update the iframe's location:
iframeWindow.location.href = "page.html";
</script>
Let's review your code:
parent.document.getElementById(id).src = parent.document.getElementById(id).src;
This works if executed from within the iframe, provided you use the correct id. You may want to use a debugger to verify that parent.document.getElementById(id) returns a reference to the correct element, and check your console to see if any exceptions are being thrown (try hitting F12). Since you didn't post your full code (including markup) there's no way I can to think of to tell what the issue is here.
Debugging tips:
check parent.location.href to make sure you are accessing the window you think you are,
check parent.document.getElementId(id) to make sure that you get an element object (as opposed to null or undefined),
check parent.document.getElementById(id).tagName to make sure you are using the correct ID (tagName should === "IFRAME")
This line:
parent.getElementById(id).location.reload();
has two problems:
getElementById() is a function of document, but it is being called from parent which is a window object, and
location is a property of a window object. You are trying to access the iframe element's location property, which does not exist. You need a reference to the iframe's window, not its element.
Besides the name method, there are other ways to get the iframe's window object:
document.getElementById('iframeId').contentWindow; // for supported browsers
window.frames["iframeName"]; // assumes name property was set on the iframe
window.frames[i]; // where i is the ordinal for the frame
If changing the src of the iframe element is not working for you, these other fixes might:
parent.document.getElementById(id).contentWindow.location.reload();
or
parent.frames["yourIframeName"].location.reload(); // requires iframe name attribute
or
parent.frames[0].location.reload(); // frames of immediate parent window
or
top.frames[0].location.reload(); // frames of top-most parent window
Caution: If using the name method be careful not to use a common value for name, like "home", for example, as it conflicts with a FireFox function called home() and so Firefox will not automatically create a reference to an iframe's window if it is named home. The most reliable method is probably to use window.frames[] as I believe that has been around for a long time (works in FF / Chrome / Safari / IE6+ (at least))
A more in-depth (but pretty minimal) example follows, tested in Chrome, FF, and IE:
File #1: frametest.html (the parent window)
<!DOCTYPE html>
<html>
<body>
<iframe id="frame1Id" name="frame1Name" src="frame1.html"></iframe>
<iframe id="frame2Id" name="frame2Name" src="frame2.html"></iframe>
</body>
</html>
File #2: frame1.html (frame 1's src)
<!DOCTYPE html>
<html>
<body>
FRAME 1
<script>
document.body.style.backgroundColor="#ccc";
setTimeout(function(){document.body.style.backgroundColor="#fff";},100);
document.write(new Date());
</script>
<input type="button" onclick="parent.document.getElementById('frame2Id').src=parent.document.getElementById('frame2Id').src;" value="Refresh frame 2 by ID"/>
<input type="button" onclick="parent.frame2Name.location.reload();" value="Refresh frame 2 by Name"/>
</body>
</html>
File #3: frame2.html (frame 2's src)
<!DOCTYPE html>
<html>
<body>
FRAME 1
<script>
document.body.style.backgroundColor="#ccc";
setTimeout(function(){document.body.style.backgroundColor="#fff";},100);
document.write(new Date());
</script>
<input type="button" onclick="parent.document.getElementById('frame1Id').src=parent.document.getElementById('frame1Id').src;" value="Refresh frame 2 by ID"/>
<input type="button" onclick="parent.frame1Name.location.reload();" value="Refresh frame 2 by Name"/>
</body>
</html>
This example demonstrates how to define and manipulate iframes by id and by name, and how to affect one iframe from within a different iframe. Depending on browser settings, origin policy may apply, but you already said that your content was all from the same domain so you should be OK there.

JavaScript to get some information from inside the HTML at an arbitrary URL?

Sorry, I'm don't know the right terminology to look this up by keyword...
So, as a simple newbie exercise, I tried to make a file "test.html" (just on my desktop) such that when I load it my browser and click the button that appears on the page, the article count from Wikipedia's main page will appear on the page under the button.
Somebody told me to try using an iframe, and I came up with this:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript"">
function get_count(){
var articlecount = document.getElementById("wiki_page").contentWindow.document.getElementById("articlecount").getElementsByTagName("a")[0].innerHTML;
document.getElementById("put_number_here").innerHTML = articlecount;
}
</script>
</head>
<body>
<iframe id="wiki_page" style="display:none" src="http://en.wikipedia.org/wiki/Main_Page"></iframe>
<input type="button" onclick="get_count()" />
<p id="put_number_here"><p>
</body>
</html>
It doesn't work, and when I test this in the scratchpad (using Firefox 17), I get this:
var x = document.getElementById("wiki_page").contentWindow.document.getElementById("articlecount").getElementsByTagName("a")[0].innerHTML;
alert(x);
/*
Exception: Permission denied to access property 'document'
#Scratchpad:10
*/
(And alert(document.getElementById("articlecount").getElementsByTagName("a")[0].innerHTML); works perfectly on http://en.wikipedia.org/wiki/Main_Page directly, so I know that's not the problem. Copying the source of the wikipedia main page to a new file "test2.html", and setting that as the src of the iframe, that also works.)
Am I just trying to do this in completely the wrong way?
You cannot access any elements inside an iFrame unless, the iFrame is referring the same domain.
for same domain calls, use this link for reference :
Calling a parent window function from an iframe
for different domain, user this link for reference :
How do I implement Cross Domain URL Access from an Iframe using Javascript? script
You can reference the other frame by using:
window.frames["wiki_page"]
Then you can reference the element in the DOM by using:
window.frames["wiki_page"].document.getElementById ("articlecount");
So in your case you could try:
var targetFrame = window.frames["wiki_page"];
Then Access the elements using:
targetFrame.document.getElementById("IDOfSomething");
Make sure your iframe is still named wiki_page etc...

How to access iframe history.length

I am trying to understand iframe history. I have created to pages A and B on a localhost server. Using an iframe I load page A first then dynamically change the iframe src to page B. Should this mean history.length=2 as two different URLs visited? It does when trying without iframes. However, by using iframes I am only getting the value 1 being returned?
<body>
<div>
<iframe src='/pageA.php' id='myframe' onload='checkHistory()' ></iframe>
</div>
</body>
</html>
<script language="javascript" type="text/javascript" >
function checkHistory()
{
document.getElementById('myframe').src='/pageB.php';
alert("Number of URLs in history list: " + history.length);
}
</script>
Am I accessing the history.lenght value for the iframe correctly or does the iframe have to be accessed like document.getElementById('myframe').history.length rather than the generic history.length property?
This has puzzled me. I have tried storing the history.length value before opening page B and comparing the values but still no luck. There must be a way that iframes store history of pages visited inside same as a browser tab window does?
Each iframe exists as its own entity: a window and document in its own right. The iframe's history is not tied to the parent's history; pages loaded in the iframe do not count toward the parent's history. You can access the iframe's own history via:
document.getElementById("myframe").contentWindow.history.length
(This assumes your iframe is loaded from the same domain as the parent, as your example indicates.)

Categories