How to access iframe history.length - javascript

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.)

Related

Assigning window.parent.location.href = window.location.href

My page contains two iframes. Both iframes represents a single page applications that contain routes for different views.
E.g.
parent window (contains the iframes): http://mypage.com
iframe1: http://mypage.com/#case/1
iframe2: http://mypage.com/#register/2
Each iframe contains a button that, when clicked, should display the entire iframe content in the iframe parent's window.
Now I wanted to assign the href attribute of an iframe's location object to the iframe's parent location object:
window.parent.location.href = window.location.href;
This code is executed inside the iframe obviously. But when executing it , the iframe reloads http://mypage.com. The parent window doesn't get reloaded at all.
Somehow the parent frame didn't reload by assigning a new URL to window.parent.location.
Additionally, I had to call reload() to get the page doing an actual reload.
window.parent.location.reload();

Open iframe page in its parent when a direct link is to one of the child pages

Hi I have multiple pages that reside in an iframe and I would like them to open in the parent page when say a search engine indexes them or people directly link to them.
Example:
-this page will be the parent page and have an iframe
-this will be first page.php
-then there will be second page.php, third page.php, fourth page.php, ect.
I would like it if someone linked to any of the pages that require the iframe to load the parent page with the iframe and load the url into that iframe. So if someone links to say third page it will load the parent page and load third page in the iframe.
I have tried the following scripts that I have found from posts across the web but they only load the parent page with the original src in the frame.
<SCRIPT LANGUAGE='javascript'>
try {
if (top == self) {
top.location.href = 'parent page.php';
}
} catch(er) { }
</SCRIPT>
And
<script type="text/javascript">
if (window == top) {
var url = 'window.location.replace("parent page.php?var1=' + window.location.href + '")';
eval(url);
}
</script>
I also tried:
<body onload="refreshFrame();">
Then I saw the post on Open iframe page in parent frame (javascript) here and it just brings up the page that was linked to and not the iframe.
The pages in the iframe are dymanically created as well so idk if that has anything to do with it or not.
But nothing seems to open the page inside of the iframe on my site it only loads the parent page with the original src first page in it. So idk if this is possible with either javascript or php.
Also idk if anyone knows how this practice effects seo there are not many words and no tags on the parent page so I was just curious about that too.
Thanks
Did you try use the base tag in you iframe pages? Something like:
<base target="_parent" />
UPDATE
OK, so in your scenario you need to know if the current page is loaded on brownser or via iframe. And if it's not on iframe, redirect to your another page where you calling the iframe.
First thing first, check if the current page is inside a iframe with js:
<script type="text/javascript">
if ( self === top ) {
//Its not an Iframe;
}
</script>
Now that we know if the page isn't load via iframe we can use a redirect inside that if statament:
window.top.location="http://www.yourdomain.com";
Now you need to make sure after redirect the page, the iframe src attribute will be the same url it was before. I'm assuming you can do that with a get parameter int the url? Let me know if find trouble in that part.
UPDATE2
Just add a get parameter in the url as i mentioned above. Something like this:
<script type="text/javascript">
if ( self === top ) {
//Its not an Iframe, needs redirect:
var url = window.location;
window.location="http://www.yourdomain.com/index.php?iframe="+url;
}
</script>
Now in your index.php ( or whatever is the page that contain the iframe):
<?php
$iframe_url = (isset($_GET['iframe']) && !empty($_GET['iframe'])) ? $_GET['iframe'] : "initial-url-content";
?>
<iframe src="<?=$iframe_url?>"></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.

How to force an iFrame to reload once it loads

I have numerous iframes that load specific content on my pages. Both the parent and iframe are on the same domain.
I have a scrollbar inside the iframe that doesn't seem to load correctly in all browsers. But when I refresh the iframe it loads perfect. I have no idea why it does this.
I have used the meta refresh, which works but I don't want the page to refresh constantly, just once.
The solution I'm looking for will reload the iFrame content after the iFrame is opened, with a minimal delay.
Edit
I realized that my page loads all of my iframes when the index is loaded. The iframes appear in a jQuery overlay, which is also loaded but visibility:hidden until called. So on this call is when I would want the iframe to be reloaded.
Could anyone help me come up with a Javascript function that reloads the iFrame when I click the link to the iFrame? I've gotten close but I know nothing about js and I keep falling short. I have a function that reloads the page, but I can't figure out how to get it called just once.
I have this so far:
<script type="text/javascript">
var pl;
var change;
pl=1;
function ifr() {
if (pl=1) {
document.location.reload([true]);
alert("Page Reloaded!");
change=1;
return change;
}
change+pl;
}
So basically it uses the document.location.reload which works to reload the page. I'm trying to then make pl change to something other than 1 so the function doesnt run again. I've been calling this JS from the body with onLoad.
All the leads on this went dead, but I did find a code snippet that worked. Not written by me, and I don't remember where it came from. Just posting to help someone should they ever have the same question.
<div class="overlay-content"> //Content container needed for CSS Styling
<div id="Reloader">
//iFrame will be reloaded into this div
</div>
//Script to reload the iframe when the page loads
<script>
function aboutReload() {
$("#Reloader").html('<iframe id="Reloader" height="355px" width="830px" scrolling="no" frameborder="0" src="about.html"></iframe>');
}
</script>
</div>
Basically just loads the iFrame source when the window with the iFrame opens, as opposed to the iFrame loading when the original page loads.
Beyond the scope of the original question, however this jQuery snippit works with cross domain iframe elements where the contentDocument.location.reload(true) method won't due to sandboxing.
//assumes 'this' is the iframe you want to reload.
$(this).replaceWith($(this).clone()); //Force a reload
Basically it replaces the whole iframe element with a copy of itself. We're using it to force resize embedded 3rd party "dumb" widgets like video players that don't notice when their size changes.
On the iframe element itself, set an onload:
iframe.onload = function() {this.contentWindow.location.reload(); this.onload = null;};
(Only works if the iframe's location is in the same domain as the main page)
Here's a complete solution to the original question:
<iframe onload="reloadOnce(this)" src="test2.html"></iframe>
<script>
var iframeLoadCount = 0;
function reloadOnce(iframe) {
iframeLoadCount ++;
if (iframeLoadCount <= 1) {
iframe.contentWindow.location.reload();
console.log("reload()");
}
}
</script>
The updated question is not really clear (what's "the link to the iFrame" and where is it in your snippet?), but you have a few issues with the code:
"calling this JS from the body with onLoad", assuming you mean an iframe's body, means the variable you're hoping to use to avoid infinite reloading will get clobbered along with the rest of the iframe's page when it's reloaded. You need to either load a slightly different URL in the iframe (and check the URL on iframe's onload before reloading) or put the flag variable in the outer page (and access it with parent.variableName - that should work I think)
if (pl=1) { should use ==, as = is always an assignment.
change+pl; has no effect.

How to call javascript function inside an adjacent iframe

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.

Categories