[previous] |
Getting the Width or Height of a Menu
You can use the code below to retrieve the width or height
of a menu. To use the procedure, you pass to it the menu number of the menu
you wish to examine, and a boolean indicating whether you wish to retrieve
the width (true) or the height (false)
of the menu in question. For example, imagine that we've created the following
two menus:
HM_Array1 = [
[300, // menu_width
, // left_position
, // top_position
, // font_color
, // mouseover_font_color
, // background_color
, // mouseover_background_color
, // border_color
, // separator_color
0, // top_is_permanent
0, // top_is_horizontal
0, // tree_is_horizontal
0, // position_under
1, // top_more_images_visible
1, // tree_more_images_visible
, // evaluate_upon_tree_show
, // evaluate_upon_tree_hide
, // right_to_left
0, // display_on_click
true, // top_is_variable_width
true] // tree_is_variable_width
["Experts","/experts/",1,0,1],
["Contents","/index2.html",1,0,0],
["Services","/index2.html",1,0,0],
["About","https://webref.com/about.html",1,0,0]
]
HM_Array1_1 = [
[],
["3-D Animation","/3d/",1,0,0],
["Design","/dlab/",1,0,0],
["HTML","https://webref.com/html/",1,0,0],
["JavaScript","/js/",1,0,0],
["Graphics","/graphics/",1,0,0],
["DHTML","/dhtml/",1,0,1],
["Perl","/perl/",1,0,0],
["XML","https://webref.com/xml/",1,0,0]
]
Both menus are variable in width, so their exact width and height will
be unknown until after they are created. Using the code below, we could retrieve
the width of the menu created via HM_Array1 with
HM_fc_GetMenuDimension("1",true) and the height of the child menu
(HM_Array1_1) with HM_fc_GetMenuDimension("1_1",false).
First let's have a look at the code itself; then we'll see how we can use
it to position menus based on their bottom or right corner positions.
The Code
function HM_fc_GetMenuDimension(menuNum,width) {
var menuID = HM_MenuIDPrefix + menuNum;
var MenuEl =
HM_DOM ? HM_MenusTarget.document.getElementById(menuID) :
HM_IE ? HM_MenusTarget.document.all(menuID) :
HM_MenusTarget[menuID];
if (MenuEl) {
if (!HM_NS4&&(!MenuEl.sizeFixed)) MenuEl.fixSize(false);
if (HM_DOM) {
return (((HM_IEnoDTD||HM_OperaQuirk)?0:(HM_BorderWidth*2))+
((width) ? parseInt(MenuEl.style.width) :
parseInt(MenuEl.style.height)));
}
else if (HM_IE) {
return ((width) ? MenuEl.style.pixelWidth :
MenuEl.style.pixelHeight);
}
else {
return ((width) ? MenuEl.clip.width : MenuEl.clip.height);
}
}
else return 0;
}
Comments
The code above is for use only with the verbose HM version 5 code set.
A version that will work with the space optimized code set is presented at the bottom
of this page.
If the menu in question does not yet exist, the function always
returns 0.
Note the awkward--yet necessary--check for sizeFixed. In
some browsers, most notably IE5 for Macintosh, we cannot reliably adjust the size of
a newly created menu until after a slight timeout (to give the browser time
to "fill in" the various parameters of the new elements based on their actual dimensions).
We account for this possibility by delaying the size adjustments after the menu is
created. Since it's possible that you will request the width/height of the menu before
the size has been adjusted, you must account for this possibility and call the
appropriate fixSize routine yourself, if necessary. Since the Netscape 4
script does not require (and in fact doesn't even include) this additional sizing,
it is excluded from the sizeFixed check.
In later version browsers, we are careful to account (or not account)
for border widths when retrieving the menu's dimensions, so that the width or height
you retrieve always contains the borders.
In Internet Explorer 4, note that we use style.pixelWidth and
style.pixelHeight instead of style.width and style.height.
In general, we've found that working with pixelWidth and pixelHeight
in this browser provides slightly more consistent results.
Usage
To use the code above in your own designs, first include it somewhere in
your pages where the HM scripts will have access to it. We recommend that you insert it
directly into your HM_Arrays.js file, which is also where the commands to call it
will be placed.
Next, call the routine as an expression in the menu top and menu left
paramaters of the menu you wish to position. Keeping in mind the quick geometry lesson
from the previous page, here are four (condensed) menu definitions that will pop up to
the right and below the mouse (the default), to the left and below the mouse, to the
right and above the mouse, and to the left and above the mouse, respectively:
// Pop up to the right and below the mouse position
HM_Array80 = [
[300, // menu_width
, // left_position
], // top_position
["Experts","/experts/",1,0,0],
["Contents","/index2.html",1,0,0]
]
// Pop up to the left and below the mouse position
HM_Array81 = [
[300, // menu_width
"mouse_x_position - HM_fc_GetMenuDimension('81',true)",
// left_position
], // top_position
["Experts","/experts/",1,0,0],
["Contents","/index2.html",1,0,0]
]
// Pop up to the right and above the mouse position
HM_Array82 = [
[300, // menu_width
, // left_position
"mouse_y_position - HM_fc_GetMenuDimension('82',false)"],
// top_position
["Experts","/experts/",1,0,0],
["Contents","/index2.html",1,0,0]
]
// Pop up to the left and above the mouse position
HM_Array83 = [
[300, // menu_width
"mouse_x_position - HM_fc_GetMenuDimension('83',true)",
// left_position
"mouse_y_position - HM_fc_GetMenuDimension('83',false)"],
// top_position
["Experts","/experts/",1,0,0],
["Contents","/index2.html",1,0,0]
]
You can rollover the following links to see the menu code in action:
Optimized Code
Using the optimized code set? Here's a version of the above
function that will work for you:
function HM_fc_GetMenuDimension(menuNum,width) {
var menuID = Hab + menuNum;
var MenuEl =
HM_DOM ? Hg.document.getElementById(menuID) :
HM_IE ? Hg.document.all(menuID) : Hg[menuID];
if (MenuEl) {
if (!HM_NS4&&(!MenuEl.hn)) MenuEl.HXq(false);
if (HM_DOM) {
return (((Hjt||Hju)?0:(Hu*2))+
((width) ? parseInt(MenuEl.style.width) :
parseInt(MenuEl.style.height)));
}
else if (HM_IE) {
return ((width)?MenuEl.style.pixelWidth:
MenuEl.style.pixelHeight);
}
else {
return ((width)?MenuEl.clip.width:MenuEl.clip.height));
}
}
else return 0;
}
Conclusion
The "coordinates-as-expressions" feature of HM provides tremendous
flexibility in the positioning of top level menus. We encourage you to experiment with
this feature whenever absolute pixel positioning is insufficient for your needs.
[previous]
Created: December 11, 2003
Revised: December 11, 2003
URL: https://www.webreference.com/dhtml/hiermenus/inprogress/11/2.html