How to reconcile frames[] with getElementsByTagName('iframe')

S

Stevo

If I have an iframe in a HTML page (no framesets involved), then that
iframe will be in the frames array. Code inside that iframe can easily
find out which index in that array it is by doing something like this:

for(var i=0;i<parent.frames.length;i++)
if(window==parent.frames)
alert("Found myself, index="+i);

The problem I'm having lies in what I can then do with knowing that
information. I can't find the position of that iframe. There's no
offsetLeft to look at. It's an array of window objects and that's all
there is to it. Its purpose is to allow you to script the frame, not to
find out where it is visually. So what I need to do is find the iframe
element. I'm finding though that the Mozilla family have the iframes in
the frames array in a different order to those returned by the
getElementsByTagName('iframe') call. IE keeps them in the same order.

So on Firefox for example:

parent.frames

is not equal to

parent.document.getElementsByTagName('iframe').item(i)

The frames array returns window objects and the getElementsByTagName
naturally returns an array of HTMLIframeElements.

How can I determine which iframe from getElementsByTagName is the same
frame I found in the frames array? They don't seem to have any common
properties at all. I don't know the id of the iframe in advance so I
can't use that in a getElementById call either.

With the window object I can look at frames.body.innerHTML and find
out anything I want about that iframe. With the getElementsByTagName I
can only find out properties of the iframe tag (.id, .width, .height etc).

At the moment I'm thinking that if I want a window handle, then I use
the frames array. If I want an object that I can find the position of,
then all I have to go on is the width and height (which I do know), but
if there are multiple iframes with the same width/height combination
then I could be matching the wrong one.
 
D

David Mark

If I have an iframe in a HTML page (no framesets involved), then that
iframe will be in the frames array. Code inside that iframe can easily

The frames property is a host object, not an array.
find out which index in that array it is by doing something like this:

for(var i=0;i<parent.frames.length;i++)
if(window==parent.frames)
alert("Found myself, index="+i);


Why would you need the index?
The problem I'm having lies in what I can then do with knowing that
information. I can't find the position of that iframe. There's no
offsetLeft to look at. It's an array of window objects and that's all

That is because it is a window object, not an element object.
there is to it. Its purpose is to allow you to script the frame, not to
find out where it is visually. So what I need to do is find the iframe
element. I'm finding though that the Mozilla family have the iframes in
the frames array in a different order to those returned by the
getElementsByTagName('iframe') call. IE keeps them in the same order.

I wouldn't count on that.
So on Firefox for example:

parent.frames

is not equal to

parent.document.getElementsByTagName('iframe').item(i)

The frames array returns window objects and the getElementsByTagName
naturally returns an array of HTMLIframeElements.


It returns a NodeList, not an array.
How can I determine which iframe from getElementsByTagName is the same
frame I found in the frames array? They don't seem to have any common
properties at all. I don't know the id of the iframe in advance so I

You forgot the name property.
can't use that in a getElementById call either.

With the window object I can look at frames.body.innerHTML and find
out anything I want about that iframe. With the getElementsByTagName I
can only find out properties of the iframe tag (.id, .width, .height etc).


You mean properties of the IFrame element.

Anyway, you can get the name property of the window object from inside
the IFrame. It will certainly match the name property of the IFrame
element in the parent document.
 
S

Stevo

David said:
for(var i=0;i<parent.frames.length;i++)
if(window==parent.frames)
alert("Found myself, index="+i);

Why would you need the index?


Well I don't. I'm just showing that an iframe can easily "find itself"
by looping through parent.frames and comparing itself against window.
When it comes to getElementsByTagName('iframe'), there's nothing that
can easily be used to compare. The .src, the .width, the .height and .id
and .name could all be matched multiple times. It may be bad form to
have two iframes with the same name/id, but such things happen and I
have to deal with it. The point is that frames doesn't suffer from any
such problems. Only one entry in frames can match against window. It's
just that having access to the frames index isn't any use to me. I want
to get the iframe element.
That is because it is a window object, not an element object.

That's what I'm saying.
I wouldn't count on that.

That's why I'm here. I'm trying to not count on that.
You forgot the name property.
you can get the name property of the window object from inside
the IFrame. It will certainly match the name property of the IFrame
element in the parent document.

That doesn't help for two reasons. One is that I don't know in advance
what the name should be. The other is that on some pages the names
aren't unique and I can't stop that.
 
D

David Mark

David said:
for(var i=0;i<parent.frames.length;i++)
if(window==parent.frames)
alert("Found myself, index="+i);

Why would you need the index?


Well I don't. I'm just showing that an iframe can easily "find itself"
by looping through parent.frames and comparing itself against window.
When it comes to getElementsByTagName('iframe'), there's nothing that
can easily be used to compare. The .src, the .width, the .height and .id
and .name could all be matched multiple times. It may be bad form to
have two iframes with the same name/id, but such things happen and I
have to deal with it. The point is that frames doesn't suffer from any
such problems. Only one entry in frames can match against window. It's
just that having access to the frames index isn't any use to me. I want
to get the iframe element.
That is because it is a window object, not an element object.

That's what I'm saying.
I wouldn't count on that.

That's why I'm here. I'm trying to not count on that.
You forgot the name property.
you can get the name property of the window object from inside
the IFrame. It will certainly match the name property of the IFrame
element in the parent document.

That doesn't help for two reasons. One is that I don't know in advance
what the name should be. The other is that on some pages the names


You don't need to know the name in advance. It is a property of the
window object. From the document inside the IFrame:

alert(window.name);
aren't unique and I can't stop that.

Then tell the page's designers to stop that as it is ridiculous to
have multiple frames with the same name. How would you target them?
 
P

pr

Stevo wrote:
....
The frames array returns window objects and the getElementsByTagName
naturally returns an array of HTMLIframeElements.

How can I determine which iframe from getElementsByTagName is the same
frame I found in the frames array? They don't seem to have any common
properties at all. I don't know the id of the iframe in advance so I
can't use that in a getElementById call either.
....

Interesting problem. Turns out you can reconcile iframes with elements
in either direction using window.frameElement or [iframe
element].contentWindow.

It's one of those spooky occasions when the same code works in IE6,
Firefox, Opera and Konqueror. This is the snippet I used for testing:

function init() {
var f = window.frames;
var e = document.getElementsByTagName("iframe");
var i;

for (i = 0; i < f.length; i++) {
if (f.frameElement == e[0]) {
alert("found element for frame");
}
}

for (i = 0; i < e.length; i++) {
if (e.contentWindow == f[0]) {
alert("found frame for element");
}
}
}

It has to run after the page has loaded (eg body onload) and IE 6 gives
me a security error if I run it from a file:/// url.
 
S

Stevo

David said:
tell the page's designers to stop that as it is ridiculous to
have multiple frames with the same name. How would you target them?

I'd love to, but my code is being included on random pages (via iframe).
I don't know the designers of the pages. I don't even know which site
I'm on.
 
S

Stevo

pr said:
Stevo said:
How can I determine which iframe from getElementsByTagName is the same
frame I found in the frames array? They don't seem to have any common
properties at all. I don't know the id of the iframe in advance so I
can't use that in a getElementById call either.

Interesting problem. Turns out you can reconcile iframes with elements
in either direction using window.frameElement or [iframe
element].contentWindow.

Thanks pr. That's EXACTLY what I needed. It works perfectly. Here's the
highlights of my final code:

for(var i=0;i<parent.frames.length;i++)
if(window==parent.frames)
my_frame=i;

for(var i=0;i<parent.frames.length;i++)
{
var ih=parent.document.getElementsByTagName('iframe').item(i);
if(ih==parent.frames[my_frame].frameElement)
my_iframes_item_index=i;
}


This solution doesn't need me to know the name/id/width/height or any
other property of the iframe :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top