View RSS Feed

molendijk

Full size object/iframe on a page; loads (a) menu(s)

Rating: 15 votes, 4.47 average.
The text/html-object can be used to include HTML, except in IE, which doesn't support the object well yet, and where, as a consequence, we should still use an iframe for that purpose.

How do we include HTML-menus (which are list-menus, normally)? As HTML-menus may have subitems, and as these subitems must be allowed to appear anywhere on the screen, an object or iframe containing the menu must have 100% size (as a principle, see below for certain restrictions).

But if we put a full size object or iframe (that is supposed to load a HTML-menu contained in a file that we will call menu.html) in a page (we'll call it the 'parent page') like this:
Code:
<!--[if IE]>
<iframe style="position:absolute;top:0px;left:0px;height:100%;width:100%" id="menu" frameborder="0" src="menu.html" allowTransparency="yes"></iframe>
<![endif]-->

<!--[if !IE]><!-->
<object id="menu" type="text/html" style="position:absolute;top:0px;left:0px;height:100%;width:100%" data="menu.html"></object>
<!--<![endif]-->
then, except for the object/iframe, the content of the parent page will be inaccessible (even if we find ways to make it visible), because the object/iframe is superimposed on the parent page. We can make the content of the parent page accessible by wrapping it (= the parent page's body content) into a div having 'position: absolute' or 'position: relative' (giving 'position:absolute' or position: relative' to the body itself of the parent page may give all sorts of unwanted results), but then, as a result, we'll have the reverse situation: the menu's subitems will be inaccessible.

There's a way out. We combine the requirements of (i) making the size of the object or iframe as big as possible and of (ii) having the parent page's body content wrapped into a div having 'position: absolute' or 'position: relative', with dynamic zIndexing. The zIndexing is done with the help of the following script, which we put in the head of menu.html:
Code:
<script type="text/javascript">
function show_subitems_of(which) {
top.document.getElementById(which).style.zIndex=1000 
}
function hide_obtrusive_ObjIfr(which) {
top.document.getElementById(which).style.zIndex=0
}
</script>
Then, also in menu.html:

(i) body section (which should NOT have any background; just to be sure, give it background: transparent!!!):
Code:
<!-- Background needed for IE, otherwise this won't work. We simply hide the background with opacity --> 
<div style="position:absolute; left:some_value; top:some_value; height:100%; width:100%; background:#ffffff; filter:alpha(opacity=0); opacity:.0" onmouseover = "hide_obtrusive_ObjIfr('menu')">
</div>
(where 'menu' is the ID of the object/iframe in which menu.html is loaded)

(ii) In each main-'li' (= li of the main part of the menu) having subitems:
Code:
onmouseover="show_subitems_of('menu')"
(where, again, 'menu' is the ID of the object/iframe in which menu.html is loaded)

As for the values of 'some_value' given in (i) above, the div should not overlap with the main items of the menu loaded in the object/iframe. This boils down to giving the div approximately the same positional values as the content's area of the parent file.

Size of the object / iframe:
If we use more than one object/iframe for inserting several menus according to the lines above, we must make sure that no part of the iframes/objects loading the menus and no part of the divs used to dynamically give a zero-index (on mouseover, see above) to whatever menu, overlaps with the main items of any menu. This implies that our objects / iframes cannot always be entirely full size. In order to verify if these requirements are met, we can momentarily give a border to the objects / iframes and some opacity to the divs.

Special IE-requirements:
To prevent IE from doing all sorts of weird things, put this in BOTH the head of the parent page and the menu page (= the page that is loaded in the object/iframe):
Code:
<!--[if IE]>
<style type="text/css">
body{width:100%; height:100%}
</style>
<![endif]-->
Links in the menu('s):
As the menu('s) is / are in an object / iframe, linking to another page cannot be simply done with href="some_page.html". We must do href="some_page.html" onclick="top.location.href=this; return false". But linking to another page from the content page (containing the object /iframe) is done in the standard way.

NOTES:
- This technique cannot be used to include HTML in the 'middle' of any text belonging to a parent file. The included HTML (here: the items of the liste-menu(s)) must be outside the range of the parent page's body content (this is normally the case when menu's are used).
- Because of the dynamic zIndexing, this method will even work in IE<5.5 (probably). But who cares.
- This technique doesn't work properly in older non-IE browsers like Mozilla 1.7.5 and Netscape 7.0. That's not a real problem: nobody uses them anymore.

DEMO here. On the pages (file 1 and file 2) of the demo, the technique described above has been used to include two separate menus: the DD All Levels Vertical Menu and the DD All Levels Horizontal Menu.

Edit:
Just to let you know, in de js-file of the All Levels Navigational Menu, you have to set enableshim: false, then comment out the
/* httpsiframesrc: "blank.htm", */.
This will stop the reloading problem that you may encounter in certain browsers, see also this.

Submit "Full size object/iframe on a page; loads (a) menu(s)" to del.icio.us Submit "Full size object/iframe on a page; loads (a) menu(s)" to StumbleUpon Submit "Full size object/iframe on a page; loads (a) menu(s)" to Google Submit "Full size object/iframe on a page; loads (a) menu(s)" to Digg

Updated 03-21-2009 at 07:47 PM by molendijk (Bug in All Levels Navigational Menu)

Categories
Post a JavaScript

Comments

  1. molendijk's Avatar
    Forget what I said above about IE<5.5. It won't work in those old IE-browsers since they treat the iframe as a windowed element.
    ===
    Arie.
    Updated 03-15-2009 at 08:52 PM by molendijk