iFramed for a crime I didn't commit
February 11, 2006 9:48 AM   Subscribe

I'm trying to get iFrames, anchors and hyperlinks to play nice together.

PLEASE don't tell me not to use iFrames. It's not my decision -- the client insists.

That said, pageA.html contains a large iFrame that is reading in content from datafile.html. In datafile.html, there are anchors. Let's say there's an anchor called "anchor01".

I've been asked to create a NEW page -- pageB.html -- that links to the pageA.html -- but it needs to link to anchor01. Of course, anchor01 is not actually IN pageA.html, so when I link to pageA.html#anchor01, it doesn't work. Anchor01 is in datafile.html, but I'm hoping there's a way to link to it (without linking directly to datafile.html) THROUGH pageA.html -- since pageA is sucking in all of datafile.

I'm open to html, css, javascript and backend solutions -- the simpler the better. And, of course, this need to be x-browser.

My old friend Google is failing me. Or maybe I'm failing him.
posted by grumblebee to Computers & Internet (12 answers total)
 
Linking to an anchor really means scrolling the that anchor.

I suspect the following will work, but I haven't tested it:

1. you need to scroll the frame's content. Presumably, this is, in javascriipt, something liike:

c.scrollTop = a.offsetTop, where c is the content in the iframe and a is the anchor within that content.

2. You need -- presumably -- to do that scrolling only when the full url is pagea.html#anchor1

So you need an onload javascript on pagea that looks at document.location.href and sees if ends with "#anchor1" -- in which case it needs to find the iframe (which you can presumably hardcode) and scroll it as in step 1.

The actual coding I leave to you.
posted by orthogonality at 10:27 AM on February 11, 2006


Rather than worrying about the exact position of an object as ortho describes, you might have better luck using Javascript's location.hash property. If you want to scroll to a particular anchor in a given page, you would use:

document.location.hash = 'anchorname';

Implementing this in pageA.html to control the location.hash in datafile.html should be fairly straightforward, depending on the scripting capability available on the server. (PHP? ASP?)

A quick test indicates this function works as expected in Mozilla, Firefox, and IE6 on Win32. I'm not at all certain about Mac browsers.
posted by Danelope at 10:41 AM on February 11, 2006


I found a forum thread where this question appears to be asked and answered. The sample code is in a zipped attachment (direct link to ZIP), but it might be worth a look.
posted by misterbrandt at 10:47 AM on February 11, 2006


Eh, I never really use iframes; a quick look shows there's a simpler answer:

Just specify (or leave out) the anchor in the iframe tag. This works in Firefox and IE.

You note that you are open to a backend solution, so:
When your backend gets a request for pageA.html#anchor1, return a version pageA.html inwhich the iframe's src attribute is "datafile.html#anchor01"

When your backend gets a request for just plain pageA.html, return a version of pageA.html where the iframe's src attribute is just plain "datafile.html".

Anchored version of pageA.html:

<html>
<body bgcolor=red>
<p>Now is the time for all good men</p>
<iframe src="iframecontained.html#anchor01">
<p>Your browser does not support iframes.</p>
</iframe>
<p>Now is the time for all good women</p>
</body>
</html>

Unanchored version of pagea.html:

<html>
<body bgcolor=red>
<p>Now is the time for all good men</p>
<iframe src="iframecontained.html">
<p>Your browser does not support iframes.</p>
</iframe>
<p>Now is the time for all good women</p>
</body>
</html>
posted by orthogonality at 10:55 AM on February 11, 2006


As an alternative to using an iframe, why not use a div with overflow:scroll and use javascript (either a simple hide/show mechanism or XMLHttpRequest) to dynamically change the content of it? You can get it nicely accessible, and it is functionally the same as an iframe.
posted by charmston at 11:42 AM on February 11, 2006


Response by poster: Thank you for all your help so far. I'm concerned that I wasn't clear enough in my initial question.

datafile.html
=========
content...
[a href="#anchor01"][/a]blah blah blah
content...

pageA.html
========
content...
[iFrame name="iFrame" src="datafile.html"]
content...

pageB.html (THE ONLY PAGE I'M ALLOWED TO MANIPULATE)
========
click [a href="pageA.html#anchor01"]here[/a].


The link on pageB doesn't work, because anchor01 isn't on pageA. It's in datafile. But it SHOULD work, because all the code from datafile is being sucked into pageA. How do I make it work? Or do I give up.

(Charmstorm, I agree -- divs -- but I'm not allowed to touch pageA or dataFile).
posted by grumblebee at 12:16 PM on February 11, 2006


click [a href="pageA.html#anchor01" target="iFrame"]here[/a].
posted by vanoakenfold at 1:13 PM on February 11, 2006


also: anchor names are not HREF's. they're NAMES, as in [a name="anchor01"]

( with no trailing [/a] )
posted by vanoakenfold at 1:16 PM on February 11, 2006


Ok now I'm mixed up. My post about names is correct. Replace my first post:

You can't link to pageA and have its iFrame load a specific anchor, because the iframe tag is what identifies what it loads, not pageB's link -- UNLESS pageB is inside the iFrame already. If this were the case, just make the link contain target="iFrame" .

Otherwise you'd have to either edit pageA or make a duplicate of pageA called pageC that has in the iframe tag:

src="datafile.html#anchor01"

It's like trying to hand someone a newspaper in such a way that the headlines change. The ink on the paper is what forms the headlines, not any special way you can hand it to someone.

If pageB is its own fullscreen non-framed page, you won't be able to link to pageA and have pageA's iFrame load a specific anchor.

You'd also have to edit the href="iFrame" in the anchor to say name="iFrame" intead. I'm not sure if the trailing /a matters, but it's not needed.
posted by vanoakenfold at 1:32 PM on February 11, 2006


The following PageB.html works here to load PageA and scroll the iFrame to the right name, with square brackets replaced by angled bracket, of course. The way it's currently set up, only FireFox works because I used the addEventListener() function to make sure PageA.html was fully loaded before referencing parts of it, but there's other ways to make sure a page is loaded, although you might have to browser probe. I'm not sure of the existence of a generic wait until page is loaded routine, although good chance they do exist.

The reason this works, naturally, is that Page B is the parent of Page A so there is coupling of the Page A window status with Page B. If they aren't coupled in some fashion, Page B can't get at the information it needs from Page A.

Anyway, I think this is pretty much want you want if there is no loading restriction on PageB, or so I interpreted it.

[html]
[head]
[script language="JavaScript" type=text/javascript]
var winA;
function goBoyGo()
{
winA = window.open("pageA.html");
winA.addEventListener("load", andGetThere, false);
}
function andGetThere()
{
winA.frames['iFrame'].location.hash = "anchor01";
winA.frames['iFrame'].focus();
}
[/script]
[/head]
[body]
[a href="javascript: goBoyGo();"]
I want pageA frame IFrame anchor anchor01
[/a]
[/body]
posted by mdevore at 2:14 PM on February 11, 2006


If you can only Manipulate pageB -- the page that links to this abortion of iframes -- then the only thing you can do is:

have pageB use javascript to open a new window containing pageA -- don't do a direct link -- and manipulete pageA.

THIS COD IS TESTED IN FIREFOX. It's on oyu to test it in other browsers.

function openPageA() {
var nw = window.open("pagea.html") ;

//use the nw javascript pointer to manipuate pagea and its contained iframe:

var ifr = mw..document.getElementsByTagName("iframe" ) ;

if( ifr && ifr[ 0 ] ) {
// this code assume the iframe of interest is the first (and only) iframe in pageA.html

ifr = ifr[ 0 ] ;
ifr.src += ifr.src + "#anchor1" ;
}
posted by orthogonality at 2:20 PM on February 11, 2006


er, of course that should be:

var ifr = mw.document.getElementsByTagName("iframe" ) ;
posted by orthogonality at 2:21 PM on February 11, 2006


« Older Insurance for a first-time car buyer   |   Problems transferring files to USB drives & SD... Newer »
This thread is closed to new comments.