While reworking my “Ryuzine Machine” webapp I wanted to get the device simulator (which is an IFRAME) to operate properly in Firefox.  For the most part the webapp worked fine in Firefox, except for previewing certain functions in the simulator due to what I consider a bug in Firefox.

To be clear I don’t think Mozilla believes it’s a bug.  They changed the way anchor links work inside an IFRAME for security reasons, but for some reason apply the same restriction even if the content in the IFRAME meets the “same origin” requirements.  The result is that when you click on an anchor link in the IFRAME it loads the parent document into the IFRAME – a recursion that totally breaks something like a webapp.

If you can prevent the anchor links from triggering you can, instead, scroll to the anchor programmatically using javascript, but to further complicate things Mozilla changed how the scrollTo point is calculated in Firefox 11 so it works differently than in Firefox 4 – 10, and it can be a DOM labyrinth trying to get proper reference for calculating if the actual parent element containing the IFRAME is a scrolling DIV rather than the body of the parent page itself.  Ugh!

A much more elegant solution is to forget about getting parent and element references outside of the IFRAME and calculating offsets – the better solution is to just use scrollIntoView()!  Never heard of it before?  Me neither, but as it turns out it is supported across browsers and you can reference the anchor by either name or id like so:

document.getElementByName(‘page5’).scrollIntoView();

document.getElementById(‘page5’).scrollIntoView();

No math, no DOM family tree monkey business.  Simply scrolls whatever scrolling container the target element is within so that the target element is in view.

Note that in XHTML and HTML5 the “name” attribute of an anchor tag is deprecated in favor of “id”, if you’re concerned with code validation. Though another cool thing about the scrollIntoView() method is you don’t need to use empty <a> tags as anchors anymore – just use any element with an id or name attribute.

References: