Hiermenus Go Forth, XXV - DHTML Lab | 16 | WebReference

Hiermenus Go Forth, XXV - DHTML Lab | 16


Hiermenus Go Forth, XXV:
Version 4.1.3 - The Complete Script (Full-Window)

HM 4.1.3 Changes

The only thing we need to do in HM to fix our problem is to identify the element that defines the page canvas. Once this is done, then instead of always referencing document.body we reference the canvas, which could be either the BODY element (document.body) or the HTML element, (document.documentElement.)

We need to create a variable to store the canvas element. We call it HM_IEcanvas and it is initialized in an IE-only part of our code early on:

if(HM_IE) {
    HM_a_ElementsCreated = [];
    function HM_f_StoreElement(el){
        HM_a_ElementsCreated[HM_a_ElementsCreated.length] = el;

    HM_IEcanvas = null;

Later, in the HM_f_StartIt() function, we assign the canvas element to HM_IEcanvas. We know if the user is using IE6 in standards-compliant mode because it is the only time that the HM_IECSS variable (see Version 4.1.2) returns true.

function HM_f_StartIt() {
    if(HM_AreCreated) return;
    if((typeof(document.body) == "undefined") || (document.body == null)) return;

    if(HM_IE) HM_IEcanvas = HM_IECSS ? document.documentElement : document.body;


Now, we simply replace all positioning-related references to document.body with HM_IEcanvas references. These are found in two functions: HM_f_PopMenu() [initial menu positioning] and HM_f_KeepInWindow() [possible menu re-positioning]:

function HM_f_PopMenu(e){
//  HM_CurrentMenu.mouseX = mouse_x_position = (HM_IE) ? (e.clientX + document.body.scrollLeft) : e.pageX;
//  HM_CurrentMenu.mouseY = mouse_y_position = (HM_IE) ? (e.clientY + document.body.scrollTop)  : e.pageY;
    HM_CurrentMenu.mouseX = mouse_x_position = (HM_IE) ? (e.clientX + HM_IEcanvas.scrollLeft) : e.pageX;
    HM_CurrentMenu.mouseY = mouse_y_position = (HM_IE) ? (e.clientY + HM_IEcanvas.scrollTop)  : e.pageY;
function HM_f_KeepInWindow() {
//  var WindowLeftEdge = (HM_IE) ? document.body.scrollLeft   : window.pageXOffset;
//  var WindowTopEdge  = (HM_IE) ? document.body.scrollTop    : window.pageYOffset;
//  var WindowWidth    = (HM_IE) ? document.body.clientWidth  : window.innerWidth;
//  var WindowHeight   = (HM_IE) ? document.body.clientHeight : window.innerHeight;
    var WindowLeftEdge = (HM_IE) ? HM_IEcanvas.scrollLeft   : window.pageXOffset;
    var WindowTopEdge  = (HM_IE) ? HM_IEcanvas.scrollTop    : window.pageYOffset;
    var WindowWidth    = (HM_IE) ? HM_IEcanvas.clientWidth  : window.innerWidth;
    var WindowHeight   = (HM_IE) ? HM_IEcanvas.clientHeight : window.innerHeight;

Now, the menus will not only be created but seen as well.

Why we like HTML-as-page-canvas

Finally, five years after the first IE DHTML browser, IE4, we get a way to determine the internal browser window measurements without waiting for the BODY to be initialized. Netscape has always had window.innerWidth and window.innerHeight, which are available for referencing immediately in the HEAD of documents. IE made us wait until we got to the BODY, i.e. to the page content, before we could determine page canvas size.

This deficiency resulted in many workarounds and script clumsily included after the BODY tag instead of in the HEAD. Those of you who have done cross-browser stuff know what I am talking about.

On the next page, the minor fix mentioned on the front page. I know, it was a long time ago.

Produced by Peter Belesis and

All Rights Reserved. Legal Notices.
Created: November 13, 2001
Revised: November 13, 2001

URL: http://www.webreference.com/dhtml/column61/9.html