|
home / bulletins / 9 / page 7
Other Implementation Issues
Rollovers
Our implementation of rollovers in HierMenus followed two
basic steps. First, when each menu item is first created, we gather all
the images that were embedded within the item, and match each of them
with the rollover images included in the HM_o_RolloverImages
images object. All those that match are saved in an array that is attached
to the item itself, and to each image is applied new properties that
contain the values of the original and rollover image src
values. Second, we apply the image sources appropriately whenever
the the menu item is highlighted or dimmed.
In order to simplify the script where item hiliting is
concerned, we've created a new, generic function, HM_f_Itemhighlight,
that is now attached to every menu item when the item is created. Whenever
we need to highlight or dim an item, we call this function, which now replaces
several redundant blocks of code in the HM script, all of which were
performing the same type of hiliting from different locations.
To further streamline the item hiliting process (which
now may include the application of rollover images) we've moved the
HM_KeepHilite logic--that's the logic that's responsible
for the continuous hiliting of a parent item while its child menus
are rolled over--from the menu item's mouseover handler to
the child menu's mouseover, instead. This reduces--and in
many cases eliminates--the brief "flicker" in the parent item
that is sometimes seen when the mouse moves from a parent item over
its child menu. (Flicker that is caused by the fact that the mouseover
for the item doesn't appear until the mouse makes it all the way into
the menu item itself; but the mouseout of the parent item is processed
as soon as the mouse rolls over the child menu's border.)
The majority of these steps went very smoothly. But, as
is usually the case, there were a few glitches.
Mac IE5: Images Not Available
You cannot gather the embedded images in Mac IE5 as
soon as the menu item itself is created. This is because the individual
properties of the item have not yet been completely updated
by the browser yet. We've seen this often in Mac IE5, and the fix here
is the same as it has always been: we must wait to ensure that the
browser has time to completely update the internal properties of the
menu item in question before we analyze it for rollover images. We do
this by simply moving the "image acquisition" phase of the rollover process
to the HM_f_FixSize procedure for Mac IE5 only.
Windows IE4: Too Much Flicker
In IE4 for windows, even after we moved the KeepHilite
logic into the MenuOver method, we still noticed a lot of
flickering while rolling over individual menu items. To reduce this,
we're implementing fromElement and toElement checking
across the board for all the item and menu mouseover and
mouseout handlers. i.e., In each of the handlers we now
have code similar to this:
if(this.contains(HM_MenusTarget.event.toElement))
return;
This is similar to logic already present in HM; but
we've previously not applied it on such a broad scale (and it was previously
not applied to all of the mouseover/out handlers of both menus and menu
items). In our testing this reduced the flicker in IE4, creating a
smoother display, and was especially helpful where image rollovers
were concerned.
Netscape 4.0x: document.images can't be
concatenated
When acquiring images in Netscape 4.x, remember that positioned
layers--including our own menu items--each include their own document.images
array. Further, any additional layers embedded within the menu items will have
their own document.images array, and so on. Thus, to gather all the
images in a NS4.x menu item, you must recursively walk through the individual
layers of the menu item, examining each document.images array in
turn, and you cannot use a single element.getElementsByTagName or
element.all.tags call as we do in the DOM and IE4 code.
In our first attempt at the Netscape 4.x code, we attempted
to recursively concatenate all of the embedded document.images arrays
in a layer into a single array for further examination. This worked well
in later NS4.x browsers, but in the earliest browsers (4.04, 4.05) the
document.images arrays refused to be flattened into a single array
when concatenated; i.e., this:
var TempArray=new Array();
TempArray = TempArray.concat(theLayer.document.images);
resulted not in a single array of images, as it did in later
Netscape 4.x browsers, but instead in an array of image arrays. Therefore
in Netscape 4.x, we simply walk through the document.image arrays
one at a time, attaching the images to our main array as we find them.
More Imaging Positioning
Only one glitch was encountered when rolling in the new
more image positioning logic. When attempting to add a specific width and
height to a more image in Internet Explorer (a specific width has always
been an option; but a specific height is new to HM 5.3, and necessary to
support top, middle, and bottom more image positioning) we found that IE
did not always honor our supplied values, instead loading the images based
on their native heights and widths. Indeed, this may have been a longstanding
problem that we've simply not noticed. To counteract this problem, we're
reassigning our desired heights and widths to the more images in
our HM_f_FixSize routine; which should give the browser enough
time to completely load the images and set its own dimensions on them before
we attempt to override them.
Flubs Fixed: Other HM Fixes and Adjustments
Horizontal more image positioning incorrect
in Safari
With our "more image" specific mentality in full gear,
we noticed an oddity in variable width more image positions in Safari
that has been present in all previous versions of HM. Specifically, some
more images seemed to have additional padding, equal to the width of
the more image itself, inserted between the menu item text and the more
image. While we provide for the placement of additional space between
the more image and the menu item's padding, the space between the more
image and the menu item text should simply be equal to the item's padding,
and no more. This extra space is most noticeable in variable width
horizontal menus (since each menu item is condensed to its shortest
possible length) but could theoretically affect any menu item.
The extra space is caused by the following peculiarity
in the Safari browser. In Safari, the offsetWidth of an element
that doesn't have a width specified includes the width
of contained, absolutely positioned objects; unless the element
itself also contains another block level element that is not
absolutely positioned. Or, in other words, given the following
construct:
<div id="theRectangle1"
style="margin:0px 0px 0px 0px;
padding:0px 0px 0px 0px;
border:0px 0px 0px 0px;
background-color:red; height:10px;
position:absolute; top:10px; left:10px;
overflow:hidden"><img
src="/art/t.gif" width="10" height="10"
alt="nothing" /><img
src="/dhtml/diner/realpos4/bluebox.gif"
width="10" height="10" alt="Blue Square"
style="position:absolute; top:0px; left:0px" /></div>
We would expect to see a 10x10 blue square on the page;
the blue square represented by the absolutely positioned "bluebox.gif"
within the outer div container. Since the inner image is absolutely
positioned, we don't expect it to adjust the width of its containing
element. This is the behavior we see in both Internet Explorer and
Gecko based browsers.
In Safari, however, we do not see a single blue square,
but instead we see a blue square with a red square (i.e, the initial
clear image of the outer div) immediately to the right of it. The result
is an overall div width of 20, not 10; and indeed the offsetWidth
as reported by Safari for theRectangle1 is 20. The resulting
"additional width" is assumed by HM to be a genuine part of the menu
item itself, which is then sized accordingly (and incorrectly).
Our initial attempt to correct the problem involved
simply reducing the width of variable width menu items by the width
of the more images (assuming the menu item in question had a more image).
While simple and elegant, the problem with this fix was that it did
not account for the fact that the problem was only evident if the
menu item itself did not contain a non-positioned block element
within it. Any HTML can be present in a menu item description, meaning
that in an array such as this:
HM_Array1_1 = [
[],
["<p>Menu Item 1</p>","link1.html",1,0,1],
["Menu Item 2","link2.html",1,0,1]
]
Menu Item 1 would not report the faulty width;
while Menu Item 2 would be reported as wider than it was. To
account for this potential difference, we're enclosing all
menu item descriptions in Safari in an additional, non-positioned
div container. Safari doesn't seem to mind the additional
container, and applying it removes all doubts as to how the
offsetWidth is reported within that browser. To avoid applying
additional structure where it is unnecessary, we apply this change
only to variable width menu items in Safari.
Horizontal Menus Not High Enough
If the last menu item in a horizontal menu was taller
than all the others, (because of specific font settings, line wrapping,
etc.) then the menu itself would not be made taller to account for it.
This was the result of a bug in our HM_f_FixSize routine and
affected all browsers.
Menus Don't Rebuild In Safari Cross-Frames
In a cross-frames scenario in the Safari Web browser only,
the menus would not automatically rebuild in the content frame when the
visitor clicked through to a page outside of the current domain and then
returned to a page within the current domain. This bug was the result of
an adjustment we made and documented in HierMenus 5.2.
When we made this adjustment, we did not properly account for some IE specific
code that was irrelevant to (and caused errors in) Safari. We've separated
out that code from the Safari logic to account for this and all is well
again.
Unnecessary horizontal scroll bars in IE4
Pages that display menus often include unnecessary horizontal
scroll bars in Internet Explorer 4; the direct result of building the initial
menus without specific left/top settings. We corrected this problem (by
intentionally building the menus offscreen, as we do in the DOM script) but immediately
introduced another; namely, that the menus cannot be immediately accessed
for purposes of adjusting their dimensions (ala our HM_f_FixSize
routine) when they are created, as their internal properties are not completely
"filled in" yet. We've previously encountered this problem in IE4 on permanently
displayed menus, but we hadn't seen it on child menus. Once we made the top/left
change mentioned above, we saw it on any IE4 menu that was displayed
as soon as it was created.
The fix is the same as the fix we originally introduced for the
permanently displayed menus: we simply ensure that the HM_f_FixSize routine
is not called on a newly created menu without an intervening timeout. This
change resulted in adjustments to both the showChild and HM_f_PopUp
logic; but the result is more consistent menu displays with no unnecessary horizontal
scrollbars in the IE4 browser.
Incorrect Popup Menu Positioning in NS4
If you set cross-frames positioning to false (HM_GL_FramesEnabled=false)
and additionally set FramesNavFramePos, then Netscape 4 would incorrectly
position pop up menus (usually to the top of the screen, or whichever dimension
you had FramesNavFramePos set to). We fixed this by checking for
HM_FramesEnabled before determining the mouse position on menu popups;
instead of checking immediately for HM_FramesNavFramePos. Thanks to
David S. Zahler of Sullivan & Company for being
the first to point out this error.
Rollover layer not created identically to original layer in NS4.x
In some rare, specific instances, we've found that the rollover
layer--the layer of text that is displayed when NSFontOver is true in
Netscape 4.x--is not identical to the original text layer in dimensions. The
result is that the rollover layer may be line-wrapped when the original layer
isn't, causing a display that appears to lose some menu item text when the item
is rolled over. We've corrected this problem by adjusting the initial width
of the rollover layer to be the full potential width of the item, instead of
only the text width of the item (which in some cases was causing the rollover
layer to be incorrectly line wrapped).
Conclusion
As always, we thank our user-base for your contributions
and suggestions, which often point us in directions (no pun intended)
that we hadn't fully analyzed before. Keep your eyes on this HM_InProgress
area for further release notes and helpful HM tutorials.
Files Changed in HM 5.3
- HM_ScriptDOM.js
- HM_ScriptOPR.js
- HM_ScriptIE4.js
- HM_ScriptNS4.js
- optimized/HM_ScriptDOM.js
- optimized/HM_ScriptOPR.js
- optimized/HM_ScriptIE4.js
- optimized/HM_ScriptNS4.js
      
[previous]
|