Let me preface this with... I have referenced this question/answers and it seems to contain clues, but i'm still missing the whole picture
Run JQuery in the context of another frame
Essentially, the structure of the index page is this
<html>
<body>
<div class="frames-wrap">
<iframe id="this-iframe" src="location.php">
</iframe>
</div>
</body>
</html>
location.php then contains a frameset (ahem, not my idea...) that has two frames that are set up like so...
<frameset cols="350,*">
<frame src="search.php" id="frame_search" name="search"/>
<frame src="edit.php" id="frame_edit" name="edit" />
</frameset>
if i want to manipulate objects between the index page and these elements how would i go about this?
I keep thinking the context should be something similar to window.parent.frames[0].document... what else am i missing?
Preface: You wont be able to access the iframes contents unless it originates from the same domain.
To select elements in your iframe you could use a jQuery call like this
element = $("#this_iframe").contents().find("#frame_search")
The key is to use the contents() function. See Traversing/contents
I think the link from technicolorenvy has the answer, but the selector has a lesser known second parameter where you can set the context.
Something like this:
var iframeDoc = document.getElementById('myIframe');
iframeDoc = (iframeDoc.contentWindow) ? iframeDoc.contentWindow : (iframeDoc.contentDocument.document) ? iframeDoc.contentDocument.document : iframeDoc.contentDocument;
// From the parent window
$('p', iframeDoc).html('Hello from parent');
http://docs.jquery.com/Core/jQuery#expressioncontext
Giving your frames ids that are valid JavaScript identifiers would help, then you could use constructs such as window.top.this_iframe.frame_edit.document as your context.
These were all helpful. I kept bombing when I was attempting to get past the iframe in the DOM. THis would appear to be from the fact i had code residing in the ready() method, but the frameset that was being called within the iframe was not loaded by the time that had $(document).ready() fired.
Thanks for all the great help and feedback!
Related
I would like to know if there is a difference between those 2 differents way of using onload() function ? (time delay, order of execution etc.) or is it exactly the same ?
Thanks
1st way :
<iframe onload="frameload()" src="script.php" name="myFrame" id="myFrame"></iframe>
<script>
function frameload(){
var iframe = document.getElementById('myFrame');
var innerDoc = iframe.contentWindow.document;
document.write(innerDoc.getElementById('ele1').value);
}
</script>
2nd way:
<iframe src="script.php" name="myFrame" id="myFrame"></iframe>
<script>
document.getElementById('myFrame').onload=function() {
var iframe = document.getElementById('myFrame');
var innerDoc = iframe.contentWindow.document;
document.write(innerDoc.getElementById('ele1').value);
}
</script>
In this particular example the effect is the same.
Anyway, if you'd need to use this inside your function, in the first case this refers to the Window object, while in the second one it refers to the iframe DOM node.
Additionally, as other pointed out, inline JS code is bad for several reasons. In a nutshell, it's preferable to separate the JS from HTML to improve readability and caching (e.g. if the code is in a separate file).
I guess there is no significant performance difference, however the 2nd approach helps you separate the concerns - markup (HTML) and functionality (JS).
Those 2 should be identical.
It's nicer to add it via
.addEventListener("load", yourFunction);
If that's not possible in your case your code should work fine.
I agree with #Lorenzo's answer and I would like to add that the second approach is a bit faster. Here are the results from firefox, please check the links I used a random link as a source for iframe:
First approach: http://screencast.com/t/esXo0jC4Qcx
Second approach: http://screencast.com/t/BlLmXcPtuZW
ofcorz both are same.
standard coding style is the second one.
But some times we have to follow the first approach.
eg. if we have a textBox with same id "txtStudentName" in Create and Edit pages and have to autocomplete it only on create page. In such condition you can use first approach to autocomplete. Othewise the code will affect both textboxes by using a single js
I have 2 frames in one page like this (home.html)
<frameset rows="50%, 50%">
<frame id="treeContent" src="treeContent.html" />
<frame id="treeStatus" src="treeStatus.html" />
</frameset>
and then in one frame (treeStatus.html) I have something like
<body style="margin: 0px">
<div id="statusText">Status bar for Tree</div>
</body>
I want from the top window to manipulate the div located in the child frame via jquery (e.g show and hide).
I have seen several questions like this and they suggest the following
$(document).ready(function(){
$('#treeStatus').contents().find("#statusText").hide();
});
I do not know if this works with iframes but in my case where I have simple frames it does not seem to work. The code is placed inside home.html
Here is some output from firebug console
>>> $('#treeStatus')
[frame#treeStatus]
>>> $('#treeStatus').contents()
[]
>>> $('#treeStatus').children()
[]
So how do I access frame elements from the top frame? Am I missing something here?
Answer
After combining both answers here, the correct way is
$('#statusText',top.frames["treeStatus"].document).hide();
For this to work the frame must have the name attribute apart from the id, like this:
<frameset rows="50%, 50%">
<frame id="treeContent" src="treeContent.html" />
<frame name="treeStatus" id="treeStatus" src="treeStatus.html" />
</frameset>
You could grab the Frame and div you are wanting to manipulate and pass it into a variable.
var statusText = top.frames["treeStatus"].document.getElementById('statusText');
Then you can do anything you want to it through jQuery.
$(statusText).whatever();
Though sometimes you just can't get around having to use frames, keep in mind that the <frame> tag is obsoleted in HTML5. If you ever plan on moving up to HTML5, you'll have to use iFrames.
I have nested frames. In my case, to make it work i used command:
var statusText =
top.document.getElementById("treeStatus").contentDocument.getElementById("statusText");
Then, as Charles already answered, you can do anything you want to it through jQuery:
$(statusText).whatever();
https://jamesmccaffrey.wordpress.com/2009/07/30/cross-frame-access-with-jquery/
$(document).ready(function(){
$("#Button1").click(function(){
$(parent.rightFrame.document).contents().find(‘#TextBox1’).val(‘Hello from left frame!’);
});
});
But I used :
$.post("content_right.php",{id:id},function(data)
$(parent.frames["content_right"].document.body).html(data) ;
});
For a pure jquery solution (that doesn't require top.frames etc), the following seems to work:
$('some selector for item from frame' ,$('frame selector')[0].contentDocument)
This has the advantage that it works for nested frames:
$('inner frame item selector', $('inner frame selector', $('outer frame selector')[0].contentDocument)[0].contentDocument)
I used the following successfully:
$( '#foo', top.frames['bar'].document )
(also works with nested frames that are automagically appended in top.frames)
is there any way how to access from iframe to parrent page (and change parrent page)?
<body>
<iframe src="frame1.html" name="frame1" height="100%"></iframe>
<div id="test1"></div>
</body>
In frame1.html is <a href=..> and I want to add text "<h1>clicked</h1>" into <div id="test1"></div>, when the <a href..> was clicked.
Thanks.
If your child page (frame1.html) is located at the same domain as the parent page, You can write a code like below in the child window :
$('#test1', parent.document).html('<h1>clicked</h1>');
The second parameter provides the context in which to search the element matched by the first parameter. The Document is here:http://api.jquery.com/jQuery/#jQuery-selector-context
jQuery( selector [, context ] )
So, your code (frame1.html) could go like this:
<a href="..."
onclick="$('#test1', parent.document).html('<h1>clicked</h1>');">click me</a>
Hope this helps.
Important note: Accessing in and out iframes is only possible, if both, parent and iframe are from the same domain, else you have no access due to Same Origin Policy.
Note, that both parts have their own document. Accessing the parent object from iframe is simple with
parent.document
and from parent it is one of the following:
window.frames['iframeName']
(window.frames.length /*gives you the number of iframes in your document*/ )
or reference it with id and do the following (watch out for support!)
var iframe = document.getElementById('iframe');
var doc = iframe.contentDocument? iframe.contentDocument:iframe.contentWindow.document;
The code below should work fine:
$(parent.document).find("#selector");
The selector is from the parent document to perform some action. For Example:
$(parent.document).find("#selector").remove();
My iframe has a variable. I want to access document holding the iframe and play with a variable defined in javascript.
e.g.
<html>
<head>
<script>var a=0;</script>
</head>
<body>
<iframe id=playmate src="document2.htm" height="150px" width="100%" scrolling="no"
border="0" frameborder="0"></iframe>>
</body>
</html>
Now in document2.htm I have a script that needs to access and manipulate var a. Can I access it directly, use jquery or plain vanilla javascript?
Its not a cross domain iframe. Promise. Same domain. Want them to play together nicely.
In the past I used to do this by getting the variable to insert a hidden input from one document into the other, but with the advent of ajax and what what I was wondering if I could just manipulate it.
So previously would write a function into the head of document, where if my var a did something, my hidden input in playmate document2 would update. Then document2 could just use hidden input and everyone was happy. When document2 played with the variable it would insert the result into hidden input in the holding document, and var a could then play properly with the new result.
I want to know if its now possible for playmate document2 to play with var a in the script without having to do hidden input. Would be very exciting.
Anyone got any ideas how to go about?
I am using jquery if that would make it easier.
I tried using this script in document2:
var c=window.document.parent.a;
But when I then output var c it tells me its notanumber. Bother. Please help. Or must I do my hidden input method.
You were close. It's actually:
window.parent.a
(window.parent returns a window object, and variables are children of the window object not the document object.)
I have a website which uses top in JavaScript to show bookshops in a panel. Now i want to add this website into another website using a frame. But when I fix the URL in the src of the frame , it changes the hierarchy of the pages or images and the bookshops are not shown.
So "top" is actually "window.top" (but since window is part of the global scope you can get away with just "top"). If you read up on what window.top does, you'll discover that it returns "a reference to the topmost window in the window hierarchy". In other words, if you have:
Frame Page B
Famed Page C
and you invoke window.top from either one, you'll get the same window object back (the one for page B).
However, if you instead have:
Frame Page A
Frame Page B
Famed Page C
window.top will always return the window object for page A, whether you call it from A, B, or C.
What I think you want to use instead (although it's hard to know without seeing your site) is window.parent (ie. "parent" if you don't want to bother with "window."). This property returns the immediate parent of the window in question. If you invoke this from C, it will ALWAYS return B's window, even if B is framed inside A. This should allow you to frame your (framing) page however you want, without messing up the logic of the innermost frame.
Hope that helps.
I'm not sure if i really understand your problem. (o;
This should be a simple form of the default frameset of your site.
<html>
<frameset rows="50,50">
<frame name="bookframe" src="bookframe.html" />
<frame src="default.html" />
</frameset>
</html>
And this should be the default.html with the javascript code to control the bookframe panel.
<html>
<body>
<script>
parent.frames["bookframe"].location.href = "uri";
</script>
</body>
</html>
As you can see, i'm using the name of the frame instead of top.
Include the framset from my first listing into a new page using an iframe and everythings is still working.
<html>
<body>
<iframe src="frameset.html" />
</body>
</html>
If your website from the beginning uses just an iframe instead of a frameset, it is still working by using the name instead of top.
HINT:
the name should be unique. there should be no javascript variable with the same name. only microsoft ie knows why!
hope that helps!