My site is setup like this:
<frameset rows="80,*">
<frame name="top" id="top" src="header.html">
<frameset id="innerframe" cols="300,*">
<frame name="nav" src="nav.html">
</frameset>
</frameset>
In header.html I have:
function fAlert() {
alert('test');
}
How can I call fAlert() in nav.html?
I tried
var fframe = parent.document.getElementById('top');
fframe.fAlert();
and also
parent.frames.top.fAlert();
but it didnt work (fAlert is undefined).
Any ideas how I can accomplish this?
First off, don't use framesets and frames. Use iframes--frames are deprecated.
Secondly, provide an id for the iframe (or frame, if you must) in order to direct the function call correctly. (You've already pretty much done this, but I'm being methodical.) I wouldn't name it 'top' because 'top' already has a meaning in terms of windows and frames.
From inside the nav frame, parent.insertYourFrameIdHere.fAlert() should work correctly. This assumes two things: 1) The page and the frame contents come from the same domain, and 2) header.html loaded correctly and there were no script errors in it. Script errors or other issues could keep the function from ever being created.
For the html in your question following should work.
window.parent.parent.frames[0].fAlert();
Related
Usually we put our JavaScript <script> tags at the bottom of an HTML document, right before the closing </body> tag, with the benefit that they are executed after all the elements are already available in the DOM and some more things.
However, I'm using a frame document1 which does have a <frameset> instead of a <body> tag. I don't want to put them in the <head> of the document because they wouldn't have immediate access the DOM elements below3. And I don't want to use <iframe>s in a standard body tag either4. I've tried
<head>
<title>Framesets are interesting</title>
</head>
<frameset cols="50%,50%">
<frame id="frame-a" src="a.html">
<frame id="frame-b" src="b.html">
<script type="text/javascript">
console.log("hello world!");
console.log(document.getElementById("frame-a")); // this is what I'm after
</script>
</frameset>
However, the script was not executed at all, it didn't even show up in the DOM inspector. Sure, a <frameset> may only contain <frame> and <noframes> tags. But, is there really no way to get scripts execute after a <frame> tag?
Just for reference, placing them after </frameset> like it's sometimes done with <body>s doesn't work either.
1: Yes, I know they're deprecated. They were just the natural choice2 for my project, a neat side-by-side view that shows two documents and scrolls them together in a sophisticated manner.
2: …and I never used them before, so I wanted to give it a try.
3: That is what I ended up with, after all an onload handler is trivial. Still the question remains, I'm curious.
4: works fine, but requires intricate CSS styling
A <script> element can only appear in either a <head> element or <body> element. It cannot appear as a child of a <frameset> element; a <frameset> can only contain <frame> elements, <noframes> elements, or other <frameset> elements. See the Transitional DTD:
<!ELEMENT FRAMESET - - ((FRAMESET|FRAME)+ & NOFRAMES?) -- window subdivision-->
Normally, browsers are happy to insert elements into other elements where they don't belong in complete defiance of what the DTD says since the DTD is just a rulebook, but this doesn't always happen (for example, you can never put any other flow element into an HTMLParagraphElement no matter how hard you try), so if a browser is refusing to place an HTMLScriptElement in an HTMLFrameSetElement, chances are this is why.
Any workarounds will involve placing a <script> element in either the frameset's <head> element, or within one of the frames. (You can also place a <script> element within a <noframes> element since <noframes> has the same content model as <body>, but this won't solve your problem for obvious reasons.)
Similar problem was solved here: Dynamically set frame src using javascript
<head>
<title>Framesets are interesting</title>
<script type="text/javascript">
function LoadPage(){
console.log("hello world!");
console.log(document.getElementById("frame-a")); // this is what I'm after
}
</script>
</head>
<frameset cols="50%,50%" onload="LoadPage();">
<frame id="frame-a" src="a.html">
<frame id="frame-b" src="b.html">
</frameset>
You can put the script by inserting a frame with a data URI:
<head>
<title>Framesets are interesting</title>
</head>
<frameset cols="50%,50%">
<frame id="frame-a" src="a.html">
<frame id="frame-b" src="b.html">
<frame src="data:text/html,<script type='text/javascript'>with(parent) {
console.log('hello world!');
console.log(document.getElementById('frame-a'));
}</script>">
</frameset>
Of course, you will need to be careful with quotes, and the script will run in another realm. You can use parent or top to access the window of the outer document.
Before anyone asks why I'm using frames: At my job, I need to test a website that uses frames. I am experimenting with using Javascript to get some information from a frame, and I am having trouble getting frames to work, period.
First, just to experiment, I created a file on my machine, test.html. It loads two frames: the left one containing another test page I wrote (test2.html), and the right frame containing some web page.
<html>
<FRAMESET cols="20%, 80%">
<FRAME name="leftFrame" src="test2.html">
<FRAME name="rightFrame" src="http://www.foxnews.com/">
</FRAMESET>
</html>
This is my other test page, test2.html. It simply has a button which, when clicked, alerts you with the length of window.frames. From what I've found online, that should tell me the number of frames there are. Problem is, the result is zero.
<html>
<head>
<script type="text/javascript">
function doSomething() {
alert(window.frames.length);
}
</script>
</head>
<body>
<button type="button" onclick="doSomething();">
Click me
</button>
</body>
</html>
How do you access a frame in JavaScript? I don't suppose this is issue comes from the fact that one of the frames points to a local file?
The window object doesn't refer to the entire browser window, but the logical window where the document object livs. The frameset, and each frame, has it's own window and document objects.
The window where the code is doesn't have any frames, you need to look at the parent window, where the frameset is:
alert(window.parent.frames.length);
For a frameset, i want to open a link from page of A frame by using onmouseover and open it in another B frame? when mouseover the link from A frame, it will open the page on B frame. Give a hint.
When I worked with <frame> it has taking a long time ago (seven or more years).
Because you didn't post any html sourcode :-|, I created a theoretical situation:
<html>
<head>
<script type="text/javascript">
function nullRand () {
//document.getElementById("frameBid").src = "myNewInternalPage.html";
document.getElementById("frameBid").src = document.getElementById("frameAid").src;
}
</script>
</head>
<frameset cols="25,*" frameborder="no" border="0" framespacing="0" framepadding="0">
<frame id="frameAid" name="frameAname" src="myHtmlFile.html" noresize>
<frame id="frameBid" name="frameBname" src="" noresize>
</frameset>
</html>
SIn my theoretical file 'myNewInternalPage.html' you have to instert the method call
An link
Note: frame is not approiate to show external content. That's why iframe exists.
Update:
After a hard fight with the OP I got something to my hands. Here is a solution:
1st: Replace the old Javascript code from 'nullRand()' with the new one
function nullRand (linkObject)
{
document.getElementById("frameBid").src = linkObject.href; // The new way to access to a frame
//top.frames["center"]..src = linkObject.href; <-- The old way to access to a frame */
}
2nd: Modyfiy the a tag -where the radio streams are listed- as follow:
...
So it should work. In my eyes you should think about a new concept for your task.
I have a website which I host myself. I do not have a static IP address so I have all traffic for my domain forwarded with masking to my DDNS account. The resulting page looks like this...
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>mydomianname.com</title>
</head>
<frameset rows="100%,*" border="0">
<frame src="http://myddns.dyndns.org/mydomainname" frameborder="0" />
<frame frameborder="0" noresize />
</frameset>
</html>
How can I update the URL of the "parent" frame as users navigate within the "child" frame?
UPDATE: Success?
I have tried doing this with javascript but had an issue getting the correct href to my javascript function with out having adverse side effects (having two windows open up, having my main window go to the wrong location, or making it so the back button didn't work right). All I needed was an attribute of my a tag to hold a value that I could use in my javascript, but would do nothing else at all. Adding the attributed value event though it is not a native attribute to the a tag works great.
The a tag...
<a onclick="url_update(this);" value="test/test.html" href="javascript:void(0);">test link</a>
and the javascript function...
function url_update(element){
base_url = 'http://mydomain.com/';
window.parent.location.href = base_url + element.getAttribute('value');
}
the resulting updated URL is...
http://mydomain.com/test/test.html
... and there are none of the previously mentioned side effects.
The only "side effect" that I would like to fix is display of the link in the info bar at the bottom of a browser window. Right now it says javascript:void(0); because that is what is written in my href attribute, but I would like it to show the updated URL when the link is hovered over... any thoughts?
It would be even better if I could scrap all of this javascript and use IIS 7 URL Rewrite 2.0 to do this instead... but I have yet to master the black art of URL rewriting.
javascript:
window.top.location = 'anther url'
--UPDATE to your updated question
use element.getAttribute('value') instead of element.value
--UPDATE #2
Use the href attribute, however, add a return false; to the onclick function:
<a onclick="url_update(this);return false;" value="test/test.html" href="test/test.html">test link</a>
Once you are doing that, you might aswell skip the value attribute and just use the href property, update your url_update function to use element.href instead of element.value
It's hard to tell from your question exactly which frames are doing what, but if The Scrum Meister's solution works for you, than you can easily implement what you want by adding this to each of your A tags.
target="_top"
Your example modified.
test link
You could also do this with jquery...
On the page where all A tags should have target="_top" you can implement the following jquery code on the page and it will dynamically add the target to all links.
<script language="javascript" type="text/javascript">
$(function()
{
$("A").attr("target","_top");
});
</script>
That is assuming that you have normail A tags with the href attribute, you can get rid of the onclick all together, no other javascript is required with the target solution.
First you need to be on the same domain... otherwise for security reasons you can not change it.
Declare and call this function in your child frame
function change(theUrl){
window.parent.reloadContent(theUrl);
}
In your parent have the following function :
function reloadContent(theUrl){
if (theUrl != ""){
document.getElementById("frameID").src= theUrl ;
}
}
I am using frameset in my page. In the frameset i have taken two frames and in the first frame i have written some javascript code. How the javascript function of the frame will call the javascript function of the main page.
Can anyone please help :)
This will do it :
parent.FrameName.FunctionName()
If your frames are set up like this:
<frameset rows="50, 50">
<frame src="menu.html" name="menu">
<frame src="main.html" name="main">
</frameset>
Then you can access functions in the frame named main from the frame named menu using top.main.functionName().
parent.main.functionName() will also work in this case, but if you have more nested levels of frames then I find it less confusing to reference top (which is always the topmost frame) and 'drill down'.