Jump to content

Iframe Mystery


nonails
 Share

Is this leader post readable?  

2 members have voted

  1. 1. Is the first post on this topic:

    • Too long?
      1
    • Too dense?
      0
    • Both?
      1
    • Neither?
      0


Recommended Posts

Hi there,Have been trying to design a navigation tool for my website - an icon bar. When the user clicks on an icon, a Javascript loads the content requested (stored in external HTML files) into an iFrame without triggering a reload of the parent.The URL format is http://www.anydomain.com/index.html?[name of content file without .html suffix]. So, for example, index.html?contact_us would load contact_us.html into the content frame. This works by having Javascript ask the parent URL what to do with the IFrame.When I first put the code together, I had a problem: while the content pane was stable in Opera, only reloading when the parent URL changed, in other browsers, the IFrame would reload infinitely, as fast as my processor would permit.This ongoingness is not what I had originally expected. In my plan, the function was to run through once only on page load. It would also be attached to the onClick event handler for the icon bar links, to run (once only) every time an icon was selected.But it wasn't to be... and after hours of fiddling, I still can't work out how to make the function do its job once only, on command, rather than constantly monitoring and reloading once it's activated... How do I turn it off?index.html looks like this:

<body onload="contentGetter()"><iframe id="contentFrame" src="opt1.html"></iframe><!-- BEGIN ICON BAR -->	<div id="opt1">		<a href="?opt1">Option 1</a>	</div>	<div id="opt2">		<a href="?opt2">Option 2</a>	</div><!-- END ICON BAR --></body>

And this is the Javascript function:

		function contentGetter()	{			contentFrame = document.getElementById('contentFrame');			parentURL = parent.document.URL;				if (parentURL.indexOf('?') != -1) {		// if there is a '?' in the parent URL,					contentFrame.src = parentURL.substring(parentURL.lastIndexOf('?')+1,parentURL.length) + ('.html');										// then the name of the page that appears in the iFrame 										// should be the bit between the last '?' in the URL and										// the end of the URL, plus '.html'				}				else {					contentFrame.src = ('opt1.html');				}		}

Suggestions would be appreciated. Am I missing something about the "lifespan" of a function?Thanks for your thoughts,No Nails

Edited by No Nails
Link to comment
Share on other sites

Do you really need Javascript for it?You can use the target attribute to open a link in an iframe:

<iframe id="contentFrame" name="contentFrame" src="opt1.html"></iframe><a href="opt1.html" target="contentFrame">Option 1</a>

Link to comment
Share on other sites

Usually designers use iFrame menu bars for one of two reasons.1. Obsolete. To keep toolbar images from reloading and making the page look sloppy. This is obsolete because modern browsers store images in memory (cache), so they do not have to be reloaded, possibly for many weeks. So if multiple pages have the same structural items, menu at the top, same background, same buttons, it usually renders instantaneously, and the user is not even aware of change.2. To keep from repeating the same code in multiple pages, and to make maintenance of the toolbar easier. The best solution to this is to write the toolbar exactly once, save it as a separate document, and include in other documents using a server-side protocol. In PHP, for example, it is the include command. Read more about that here.

Link to comment
Share on other sites

Thank you both for your thoughts.

Do you really need Javascript for it?You can use the target attribute to open a link in an iframe:
I would like each possible parent-content page combination to have a unique URL for ease of navigation, referencing & bookmarking.
Usually designers use iFrame menu bars for one of two reasons.1. Obsolete. To keep toolbar images from reloading and making the page look sloppy. This is obsolete because modern browsers store images in memory (cache), so they do not have to be reloaded, possibly for many weeks. So if multiple pages have the same structural items, menu at the top, same background, same buttons, it usually renders instantaneously, and the user is not even aware of change.2. To keep from repeating the same code in multiple pages, and to make maintenance of the toolbar easier. The best solution to this is to write the toolbar exactly once, save it as a separate document, and include in other documents using a server-side protocol. In PHP, for example, it is the include command. Read more about that here.
The iFrame is actually for the page content, not the menu bar.Was using an iFrame for both of the above reasons. Keeping it client side because each content page has its own meta info and I want search engines to treat all the content pages as different and link to them individually, eg. contact_us.html. Each content page has a script which ensures it is always inside its parent, redirecting to the index.html?[that content page] URL format if it isn't.Forgive me if this seems like a doomed exercise in irrational exuberance. If nothing else, I would like to better understand Javascript through it... How do you structure a script to run through and do its job once only and then turn off, rather than be activated by an event handler once only, but treat the job as continuous?And what is contentFrame.src = contentFrame.src; all about? Sounds tautological & semantically empty - the kind of messy code that works by inducing an error.Again, your efforts appreciated.Cheers,No Nails Edited by No Nails
Link to comment
Share on other sites

I would like each possible parent-content page combination to have a unique URL for ease of navigation, referencing & bookmarking.
This is one of the many reasons why frames are discouraged for layout. They're deprecated in HTML 4.01 and XHTML 1.0 Strict.You should try PHP for that.
Link to comment
Share on other sites

I have no idea why someone would suggest contentFrame.src = contentFrame.src. It doesn't sound like anything one of us would suggest.It really makes no difference whether the content or the toolbar is in the iFrame. The solution I suggested works more or less the same.Nothing wrong with "exuberance" per se. But you're putting an awful lot of effort into a defunct technique. There are plenty of reasonable things that JavaScript can do that are more worth the time and energy.

How do you structure a script to run through and do its job once only and then turn off, rather than be activated by an event handler once only, but treat the job as continuous?
I'm very close to understanding your intent here, but not close enough.Part of my challenge is that I rarely think of a whole script as having one job. JavaScript in a browser is mostly driven by events. Individual functions, or clusters of related functions, have a job, and the job is usually executed in response to an event. Event listeners are bound to page element objects, and the most common event to listen for is a mouse click.By "continuous," are you referring to event handlers that continuously listen for events? This post and this one suggest possibilities. (Strictly speaking, it is the DOM that listens for events and passes them to the correct function. But it is common to discuss the process as if it were the object itself that does the listening.) Edited by Deirdre's Dad
Link to comment
Share on other sites

Deirdre's Dad,

I'm very close to understanding your intent here, but not close enough....By "continuous," are you referring to event handlers that continuously listen for events? This post and this one suggest possibilities. (Strictly speaking, it is the DOM that listens for events and passes them to the correct function. But it is common to discuss the process as if it were the object itself that does the listening.)
Your posts describe (with great elegance) the use of a generic object marker, the linking of objects & methods, and the attribution of DOM activities to objects in order to explain them with ease, all three of which I find fascinating, and upon re-reading my confusing, misplaced line about "be[ing] attached to the onClick event handler for the icon bar links," I appreciate why you directed me to them (particularly the first). However, I think I need to explain my difficulty better.The original problem was that when contentGetter() was triggered by either the onLoad event handler (attached to the body) or the onClick event handler (attached to the links), in most browsers/DOM environments the content frame would not just jump to the target page once, but keep on doing it - even when the correct page was already loaded in the content frame - causing endless reloading.In order to explain why I think this was happening, I'll show you a way I tried to solve my problem. Please take the following example with the caveat that I'm not 100% sure it doesn't work... it didn't last time I checked, but I'm going away to test it again now that my Javascripting is better:
function contentGetter()	{			contentFrame = document.getElementById('contentFrame');			parentURL = parent.document.URL;						if (parentURL.indexOf('?') != -1) {									var i = 0;									for (i = 0; i < 1; i++) {					// only do it once!												contentFrame.src = parentURL.substring(parentURL.lastIndexOf('?')+1,parentURL.length) + ('.html');									}				}				else {					contentFrame.src = ('opt1.html');				}		}

This didn't stop the infinite reloading problem. The reason seems to be that even if you tell Javascript to run the command only once, once commanded, the DOM will keep on listening. DOMs treat the command as ongoing or continuous.The way some DOMs "listen", then, must be by executing that same command over and over (Firefox, Safari). Other, more passive DOMs wait for a change in the relevant object's behaviour before executing the command again (Opera).So, assuming that analysis is correct, my question is, "How do I stop the DOM from listening after it has correctly loaded the target page (once), and just chill out until that function is called again by an event handler?"With thanks & regards

Edited by No Nails
Link to comment
Share on other sites

First, if you only want to run a line of code once, you don't need to put it in a loop, just write the line of code. It's not going to execute a single line of code more than once unless it's in a loop.The body onload event only fires once, it doesn't keep firing. It only fires once, after everything in the body has been loaded. You can add an alert to your contentGetter function to verify that, you should only see one alert.Where you might see a problem is if you have an onload event in the document which you are loading inside the iframe. If your contentGetter function runs onload when the document is loaded inside the iframe, and the function reloads the iframe, then that will create an infinite loop because the page inside the iframe will run the function on load, which reloads the document, then it runs the function again, etc. You should be able to see why that's a loop. Is that what your situation is?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...