Lance_Frisbee
asked on
IE BUG - Find the JavaScript Error!
I have a dropdown navigation script that I finally got working... but now it is crapping out in Internet Explorer on PC and in MAC. It works perfectly in Firefox (PC and MAC) (imagine that) and on Safari (MAC). I can't seem to track down and fix the error.
I am going to paste my source file... and my include files. Please help me out if you would be so kind... This fix is needed in a hurry, so any fast help would be excellent. Thank you.
REMEMBER - This is only an IE Error - I have browser handling in the script...
<!-- THIS IS THE SOURCE HTML FILE -->
http://www.lancefrisbee.com/test/dropdown
<!-- THIS IS THE CONTENTS OF THE TWO JAVASCRIPT FILES THAT COULD BE THE STEM OF THE PROBLEM -->
<!-- file #1: menucode.css (more likely root of the error) -->
//<!--
function Browser() {
var ua, s, i;
this.isIE = false; // Internet Explorer
this.isOP = false; // Opera
this.isSA = false; // Safari
this.isNS = false; // Netscape
this.version = null;
ua = navigator.userAgent;
s = "Opera";
if ((i = ua.indexOf(s)) >= 0) {
this.isOP = true;
this.version = parseFloat(ua.substr(i + s.length));
return;
}
// Detect Safari for special case positioning fix
s = "Safari";
if ((i = ua.indexOf(s)) >= 0) {
this.isSA = true;
this.version = parseFloat(ua.substr(i + s.length));
}
s = "Netscape6/";
if ((i = ua.indexOf(s)) >= 0) {
this.isNS = true;
this.version = parseFloat(ua.substr(i + s.length));
return;
}
// Treat any other "Gecko" browser as Netscape 6.1.
s = "Gecko";
if ((i = ua.indexOf(s)) >= 0) {
this.isNS = true;
this.version = 6.1;
return;
}
s = "MSIE";
if ((i = ua.indexOf(s))) {
this.isIE = true;
this.version = parseFloat(ua.substr(i + s.length));
return;
}
}
var browser = new Browser();
//------------------------ ---------- ---------- ---------- ---------- ---------- --
// Code for handling the menu bar and active button.
//------------------------ ---------- ---------- ---------- ---------- ---------- --
var activeButton = null;
/* [MODIFIED] This code commented out, not needed for activate/deactivate
on mouseover.
// Capture mouse clicks on the page so any active button can be
// deactivated.
if (browser.isIE)
document.onmousedown = pageMousedown;
else
document.addEventListener( "mousedown ", pageMousedown, true);
function pageMousedown(event) {
var el;
// If there is no active button, exit.
if (activeButton == null)
return;
// Find the element that was clicked on.
if (browser.isIE)
el = window.event.srcElement;
else
el = (event.target.tagName ? event.target : event.target.parentNode);
// If the active button was clicked on, exit.
if (el == activeButton)
return;
// If the element is not part of a menu, reset and clear the active
// button.
if (getContainerWith(el, "DIV", "menu") == null) {
resetButton(activeButton);
activeButton = null;
}
}
[END MODIFIED] */
function buttonClick(event, menuId) {
var button;
// Get the target button element.
if (browser.isIE)
button = window.event.srcElement;
else
button = event.currentTarget;
// Blur focus from the link to remove that annoying outline.
button.blur();
// Associate the named menu to this button if not already done.
// Additionally, initialize menu display.
if (button.menu == null) {
button.menu = document.getElementById(me nuId);
if (button.menu.isInitialized == null)
menuInit(button.menu);
}
// [MODIFIED] Added for activate/deactivate on mouseover.
// Set mouseout event handler for the button, if not already done.
if (button.onmouseout == null)
button.onmouseout = buttonOrMenuMouseout;
// Exit if this button is the currently active one.
if (button == activeButton)
return false;
// [END MODIFIED]
// Reset the currently active button, if any.
if (activeButton != null)
resetButton(activeButton);
// Activate this button, unless it was the currently active one.
if (button != activeButton) {
depressButton(button);
activeButton = button;
if (browser.isIE)
{
activeButton.src = "_gfx/" + activeButton.id + "-on.jpg";
}
else
{
var images = activeButton.getElementsBy TagName("i mg");
for (ti = 0; ti < images.length; ti++)
{
var thisImage = images[ti];
if ((thisImage.src) && (activeButton.id)){
thisImage.src = "_gfx/" + thisImage.id + "-on.jpg";
}
}
}
}
else
activeButton = null;
return false;
}
function buttonMouseover(event, menuId) {
var button;
// [MODIFIED] Added for activate/deactivate on mouseover.
// Activates this button's menu if no other is currently active.
if (activeButton == null) {
buttonClick(event, menuId);
return;
}
// [END MODIFIED]
// Find the target button element.
if (browser.isIE)
button = window.event.srcElement;
else
button = event.currentTarget;
// If any other button menu is active, make this one active instead.
if (activeButton != null && activeButton != button)
buttonClick(event, menuId);
}
function depressButton(button) {
var x, y;
// Update the button's style class to make it look like it's
// depressed.
button.className += " menuButtonActive";
// [MODIFIED] Added for activate/deactivate on mouseover.
// Set mouseout event handler for the button, if not already done.
if (button.onmouseout == null)
button.onmouseout = buttonOrMenuMouseout;
if (button.menu.onmouseout == null)
button.menu.onmouseout = buttonOrMenuMouseout;
// [END MODIFIED]
// Position the associated drop down menu under the button and
// show it.
x = getPageOffsetLeft(button);
y = getPageOffsetTop(button) + button.offsetHeight;
// For IE, adjust position.
if (browser.isIE) {
x += button.offsetParent.client Left;
y += button.offsetParent.client Top;
}
button.menu.style.left = x + "px";
button.menu.style.top = y + "px";
if (browser.isOP) {
y -= 18;
button.menu.style.top = y + "px";
}
button.menu.style.visibili ty = "visible";
// For IE; size, position and show the menu's IFRAME as well.
if (button.menu.iframeEl != null)
{
button.menu.iframeEl.style .left = button.menu.style.left;
button.menu.iframeEl.style .top = button.menu.style.top;
button.menu.iframeEl.style .width = button.menu.offsetWidth + "px";
button.menu.iframeEl.style .height = button.menu.offsetHeight + "px";
button.menu.iframeEl.style .display = "";
}
}
function resetButton(button) {
// Restore the button's style class.
if (browser.isIE)
{
button.src = "_gfx/" + button.id + "-off.jpg";
}
else
{
var images = button.getElementsByTagNam e("img");
for (ti = 0; ti < images.length; ti++)
{
var thisImage = images[ti];
if ((thisImage.src) && (button.id))
{
thisImage.src = "_gfx/" + thisImage.id + "-off.jpg";
}
}
}
removeClassName(button, "menuButtonActive");
// Hide the button's menu, first closing any sub menus.
if (button.menu != null) {
closeSubMenu(button.menu);
button.menu.style.visibili ty = "hidden";
// For IE, hide menu's IFRAME as well.
if (button.menu.iframeEl != null)
button.menu.iframeEl.style .display = "none";
}
}
//------------------------ ---------- ---------- ---------- ---------- ---------- --
// Code to handle the menus and sub menus.
//------------------------ ---------- ---------- ---------- ---------- ---------- --
function menuMouseover(event) {
var menu;
// Find the target menu element.
if (browser.isIE)
menu = getContainerWith(window.ev ent.srcEle ment, "DIV", "menu");
else
menu = event.currentTarget;
// Close any active sub menu.
if (menu.activeItem != null)
closeSubMenu(menu);
}
function menuItemMouseover(event, menuId) {
var item, menu, x, y;
// Find the target item element and its parent menu element.
if (browser.isIE)
item = getContainerWith(window.ev ent.srcEle ment, "A", "menuItem");
else
item = event.currentTarget;
menu = getContainerWith(item, "DIV", "menu");
// Close any active sub menu and mark this one as active.
if (menu.activeItem != null)
closeSubMenu(menu);
menu.activeItem = item;
// Highlight the item element.
item.className += " menuItemHighlight";
// Initialize the sub menu, if not already done.
if (item.subMenu == null) {
item.subMenu = document.getElementById(me nuId);
if (item.subMenu.isInitialize d == null)
menuInit(item.subMenu);
}
// [MODIFIED] Added for activate/deactivate on mouseover.
// Set mouseout event handler for the sub menu, if not already done.
if (item.subMenu.onmouseout == null)
item.subMenu.onmouseout = buttonOrMenuMouseout;
// [END MODIFIED]
// Get position for submenu based on the menu item.
x = getPageOffsetLeft(item) + item.offsetWidth;
y = getPageOffsetTop(item);
// Adjust position to fit in view.
var maxX, maxY;
if (browser.isIE) {
maxX = Math.max(document.document Element.sc rollLeft, document.body.scrollLeft) +
(document.documentElement. clientWidt h != 0 ? document.documentElement.c lientWidth : document.body.clientWidth) ;
maxY = Math.max(document.document Element.sc rollTop, document.body.scrollTop) +
(document.documentElement. clientHeig ht != 0 ? document.documentElement.c lientHeigh t : document.body.clientHeight );
}
if (browser.isOP || browser.isSA) {
maxX = document.documentElement.s crollLeft + window.innerWidth;
maxY = document.documentElement.s crollTop + window.innerHeight;
}
else if (browser.isNS) {
maxX = window.scrollX + window.innerWidth;
maxY = window.scrollY + window.innerHeight;
}
maxX -= item.subMenu.offsetWidth;
maxY -= item.subMenu.offsetHeight;
if (x > maxX)
x = Math.max(0, x - item.offsetWidth - item.subMenu.offsetWidth
+ (menu.offsetWidth - item.offsetWidth));
y = Math.max(0, Math.min(y, maxY));
// Position and show the sub menu.
item.subMenu.style.left = x + "px";
item.subMenu.style.top = y + "px";
// Safari sets the sub-menu too far to the right and too far down - adjust positioning to bring them closer to what they should be
if (browser.isSA) {
x -= 8;
y -= 16;
item.subMenu.style.left = x + "px";
item.subMenu.style.top = y + "px";
}
if (browser.isOP) {
y -= 15;
item.subMenu.style.top = y + "px";
}
item.subMenu.style.visibil ity = "visible";
// For IE; size, position and display the menu's IFRAME as well.
if (item.subMenu.iframeEl != null)
{
item.subMenu.iframeEl.styl e.left = item.subMenu.style.left;
item.subMenu.iframeEl.styl e.top = item.subMenu.style.top;
item.subMenu.iframeEl.styl e.width = item.subMenu.offsetWidth + "px";
item.subMenu.iframeEl.styl e.height = item.subMenu.offsetHeight + "px";
item.subMenu.iframeEl.styl e.display = "";
}
// Stop the event from bubbling.
if (browser.isIE)
window.event.cancelBubble = true;
else
event.stopPropagation();
}
function closeSubMenu(menu) {
if (menu == null || menu.activeItem == null)
return;
// Recursively close any sub menus.
if (menu.activeItem.subMenu != null) {
closeSubMenu(menu.activeIt em.subMenu );
menu.activeItem.subMenu.st yle.visibi lity = "hidden";
// For IE, hide the sub menu's IFRAME as well.
if (menu.activeItem.subMenu.i frameEl != null)
menu.activeItem.subMenu.if rameEl.sty le.display = "none";
menu.activeItem.subMenu = null;
}
// Deactivate the active menu item.
removeClassName(menu.activ eItem, "menuItemHighlight");
menu.activeItem = null;
}
// [MODIFIED] Added for activate/deactivate on mouseover. Handler for mouseout
// event on buttons and menus.
function buttonOrMenuMouseout(event ) {
var el;
// If there is no active button, exit.
if (activeButton == null)
return;
// Find the element the mouse is moving to.
if (browser.isIE)
el = window.event.toElement;
else if (event.relatedTarget != null)
el = (event.relatedTarget.tagNa me ? event.relatedTarget : event.relatedTarget.parent Node);
// If the element is not part of a menu, reset the active button.
if (getContainerWith(el, "DIV", "menu") == null) {
resetButton(activeButton);
activeButton = null;
}
}
// [END MODIFIED]
//------------------------ ---------- ---------- ---------- ---------- ---------- --
// Code to initialize menus.
//------------------------ ---------- ---------- ---------- ---------- ---------- --
function menuInit(menu) {
var itemList, spanList;
var textEl, arrowEl;
var itemWidth;
var w, dw;
var i, j;
// For IE, replace arrow characters.
if (browser.isIE) {
menu.style.lineHeight = "2.5ex";
spanList = menu.getElementsByTagName( "SPAN");
for (i = 0; i < spanList.length; i++)
if (hasClassName(spanList[i], "menuItemArrow")) {
spanList[i].style.fontFami ly = "Webdings";
spanList[i].firstChild.nod eValue = "4";
}
}
// Find the width of a menu item.
itemList = menu.getElementsByTagName( "A");
if (itemList.length > 0)
itemWidth = itemList[0].offsetWidth;
else
return;
// For items with arrows, add padding to item text to make the
// arrows flush right.
for (i = 0; i < itemList.length; i++) {
spanList = itemList[i].getElementsByT agName("SP AN");
textEl = null;
arrowEl = null;
for (j = 0; j < spanList.length; j++) {
if (hasClassName(spanList[j], "menuItemText"))
textEl = spanList[j];
if (hasClassName(spanList[j], "menuItemArrow"))
arrowEl = spanList[j];
}
if (textEl != null && arrowEl != null) {
textEl.style.paddingRight = (itemWidth
- (textEl.offsetWidth + arrowEl.offsetWidth)) + "px";
// For Opera, remove the negative right margin to fix a display bug.
if (browser.isOP)
arrowEl.style.marginRight = "0px";
}
}
// Fix IE hover problem by setting an explicit width on first item of
// the menu.
if (browser.isIE) {
w = itemList[0].offsetWidth;
itemList[0].style.width = w + "px";
dw = itemList[0].offsetWidth - w;
w -= dw;
itemList[0].style.width = w + "px";
}
// Fix the IE display problem (SELECT elements and other windowed controls
// overlaying the menu) by adding an IFRAME under the menu.
if (browser.isIE) {
menu.iframeEl = menu.parentNode.insertBefo re(documen t.createEl ement("IFR AME"), menu);
menu.iframeEl.style.displa y = "none";
menu.iframeEl.style.positi on = "absolute";
}
// Mark menu as initialized.
menu.isInitialized = true;
}
//------------------------ ---------- ---------- ---------- ---------- ---------- --
// General utility functions.
//------------------------ ---------- ---------- ---------- ---------- ---------- --
function getContainerWith(node, tagName, className) {
// Starting with the given node, find the nearest containing element
// with the specified tag name and style class.
while (node != null) {
if (node.tagName != null && node.tagName == tagName &&
hasClassName(node, className))
return node;
node = node.parentNode;
}
return node;
}
function hasClassName(el, name) {
var i, list;
// Return true if the given element currently has the given class
// name.
list = el.className.split(" ");
for (i = 0; i < list.length; i++)
if (list[i] == name)
return true;
return false;
}
function removeClassName(el, name) {
var i, curList, newList;
if (el.className == null)
return;
// Remove the given class name from the element's className property.
newList = new Array();
curList = el.className.split(" ");
for (i = 0; i < curList.length; i++)
if (curList[i] != name)
newList.push(curList[i]);
el.className = newList.join(" ");
}
function getPageOffsetLeft(el) {
var x;
// Return the x coordinate of an element relative to the page.
x = el.offsetLeft;
if (el.offsetParent != null)
x += getPageOffsetLeft(el.offse tParent);
return x;
}
function getPageOffsetTop(el) {
var y;
// Return the x coordinate of an element relative to the page.
y = el.offsetTop;
if (el.offsetParent != null)
y += getPageOffsetTop(el.offset Parent);
return y;
}
// -->
<!-- FILE#2: menuinit.css -->
function addEvent(elm, evType, fn, useCapture)
{
// addEvent
// cross-browser event handling for IE5+, NS6 and Mozilla
// By Scott Andrew
if (elm.addEventListener)
{
elm.addEventListener(evTyp e, fn, useCapture);
return true;
}
else if (elm.attachEvent)
{
var r = elm.attachEvent("on"+evTyp e, fn);
return r;
}
else
{
// alert("Handler could not be added");
}
}
function removeEvent(elm, evType, fn, useCapture)
{
// removeEvent
// cross-browser event handling for IE5+, NS6 and Mozilla
// By Scott Andrew
if (elm.removeEventListener)
{
elm.removeEventListener(ev Type, fn, useCapture);
return true;
}
else if (elm.detatchEvent)
{
var r = elm.detachEvent("on"+evTyp e, fn);
return r;
}
else
{
// alert("Handler could not be removed");
}
}
function menu_init()
{
// Find all divTag with class menubar and assign functions to A and IMG tags
if (!document.getElementsByTa gName)
{
return;
}
var divTag = document.getElementsByTagN ame("div") ;
for (di=0;di<divTag.length;di+ +)
{
var thisDiv = divTag[di];
if (((' '+thisDiv.className+' ').indexOf("menuBar") != -1) && (thisDiv.id))
{
menu_makemenu(thisDiv);
}
else
{
if (((' '+thisDiv.className+' ').indexOf("menu") != -1) && (thisDiv.id))
{
menu_makesubmenu(thisDiv);
}
}
}
}
function menu_makemenu(menu)
{
var anchors = menu.getElementsByTagName( "a");
for (i = 0; i < anchors.length; i++)
{
var thisAnchor = anchors[i];
if (((' '+thisAnchor.className+' ').indexOf("menuButton") != -1) && (thisAnchor.id))
{
var images = thisAnchor.getElementsByTa gName("img ");
for (ti = 0; ti < images.length; ti++)
{
var thisImage = images[ti];
if ((thisImage.src) && (thisAnchor.id))
{
thisImage.style.width = (thisImage.width);
thisImage.style.height = (thisImage.height + 0.1);
}
}
if (thisAnchor.id)
{
thisAnchor.onmouseover=fun ction(even t){
buttonMouseover(event, this.id+"menu");
}
thisAnchor.onmouseout=func tion(event ){
buttonOrMenuMouseout(event );
}
}
}
}
}
function menu_makesubmenu(menu)
{
if ((!((' '+menu.id+' ').indexOf("submenu") != -1)))
{
menu.onmouseover=function( event){
menuMouseover(event);
}
}
var anchors = menu.getElementsByTagName( "a");
tagged = 0;
for (si = 0; si < anchors.length; si++)
{
var thisAnchor = anchors[si];
if (((' '+thisAnchor.className+' ').indexOf("menuItem") != -1) && (menu.id))
{
if(thisAnchor.id )
{
var spans = thisAnchor.getElementsByTa gName("spa n");
for (sti = 0; sti < spans.length; sti++)
{
var thisSpan = spans[sti];
if (((' '+thisSpan.className+' ').indexOf("menuItemText") != -1) && (thisAnchor.id))
{
thisAnchor.onmouseover=fun ction(even t){
menuItemMouseover(event, this.id+"menu");
}
sti = spans.length;
}
}
}
}
}
}
Open http://www.lancefrisbee.com/testing/dropdown in Firefox to see how it should act, then again in IE - and you'll see what I'm talking about.
Any help would be GREATLY appreciated and rewarded in kind.
Thank you,
Lance
I am going to paste my source file... and my include files. Please help me out if you would be so kind... This fix is needed in a hurry, so any fast help would be excellent. Thank you.
REMEMBER - This is only an IE Error - I have browser handling in the script...
<!-- THIS IS THE SOURCE HTML FILE -->
http://www.lancefrisbee.com/test/dropdown
<!-- THIS IS THE CONTENTS OF THE TWO JAVASCRIPT FILES THAT COULD BE THE STEM OF THE PROBLEM -->
<!-- file #1: menucode.css (more likely root of the error) -->
//<!--
function Browser() {
var ua, s, i;
this.isIE = false; // Internet Explorer
this.isOP = false; // Opera
this.isSA = false; // Safari
this.isNS = false; // Netscape
this.version = null;
ua = navigator.userAgent;
s = "Opera";
if ((i = ua.indexOf(s)) >= 0) {
this.isOP = true;
this.version = parseFloat(ua.substr(i + s.length));
return;
}
// Detect Safari for special case positioning fix
s = "Safari";
if ((i = ua.indexOf(s)) >= 0) {
this.isSA = true;
this.version = parseFloat(ua.substr(i + s.length));
}
s = "Netscape6/";
if ((i = ua.indexOf(s)) >= 0) {
this.isNS = true;
this.version = parseFloat(ua.substr(i + s.length));
return;
}
// Treat any other "Gecko" browser as Netscape 6.1.
s = "Gecko";
if ((i = ua.indexOf(s)) >= 0) {
this.isNS = true;
this.version = 6.1;
return;
}
s = "MSIE";
if ((i = ua.indexOf(s))) {
this.isIE = true;
this.version = parseFloat(ua.substr(i + s.length));
return;
}
}
var browser = new Browser();
//------------------------
// Code for handling the menu bar and active button.
//------------------------
var activeButton = null;
/* [MODIFIED] This code commented out, not needed for activate/deactivate
on mouseover.
// Capture mouse clicks on the page so any active button can be
// deactivated.
if (browser.isIE)
document.onmousedown = pageMousedown;
else
document.addEventListener(
function pageMousedown(event) {
var el;
// If there is no active button, exit.
if (activeButton == null)
return;
// Find the element that was clicked on.
if (browser.isIE)
el = window.event.srcElement;
else
el = (event.target.tagName ? event.target : event.target.parentNode);
// If the active button was clicked on, exit.
if (el == activeButton)
return;
// If the element is not part of a menu, reset and clear the active
// button.
if (getContainerWith(el, "DIV", "menu") == null) {
resetButton(activeButton);
activeButton = null;
}
}
[END MODIFIED] */
function buttonClick(event, menuId) {
var button;
// Get the target button element.
if (browser.isIE)
button = window.event.srcElement;
else
button = event.currentTarget;
// Blur focus from the link to remove that annoying outline.
button.blur();
// Associate the named menu to this button if not already done.
// Additionally, initialize menu display.
if (button.menu == null) {
button.menu = document.getElementById(me
if (button.menu.isInitialized
menuInit(button.menu);
}
// [MODIFIED] Added for activate/deactivate on mouseover.
// Set mouseout event handler for the button, if not already done.
if (button.onmouseout == null)
button.onmouseout = buttonOrMenuMouseout;
// Exit if this button is the currently active one.
if (button == activeButton)
return false;
// [END MODIFIED]
// Reset the currently active button, if any.
if (activeButton != null)
resetButton(activeButton);
// Activate this button, unless it was the currently active one.
if (button != activeButton) {
depressButton(button);
activeButton = button;
if (browser.isIE)
{
activeButton.src = "_gfx/" + activeButton.id + "-on.jpg";
}
else
{
var images = activeButton.getElementsBy
for (ti = 0; ti < images.length; ti++)
{
var thisImage = images[ti];
if ((thisImage.src) && (activeButton.id)){
thisImage.src = "_gfx/" + thisImage.id + "-on.jpg";
}
}
}
}
else
activeButton = null;
return false;
}
function buttonMouseover(event, menuId) {
var button;
// [MODIFIED] Added for activate/deactivate on mouseover.
// Activates this button's menu if no other is currently active.
if (activeButton == null) {
buttonClick(event, menuId);
return;
}
// [END MODIFIED]
// Find the target button element.
if (browser.isIE)
button = window.event.srcElement;
else
button = event.currentTarget;
// If any other button menu is active, make this one active instead.
if (activeButton != null && activeButton != button)
buttonClick(event, menuId);
}
function depressButton(button) {
var x, y;
// Update the button's style class to make it look like it's
// depressed.
button.className += " menuButtonActive";
// [MODIFIED] Added for activate/deactivate on mouseover.
// Set mouseout event handler for the button, if not already done.
if (button.onmouseout == null)
button.onmouseout = buttonOrMenuMouseout;
if (button.menu.onmouseout == null)
button.menu.onmouseout = buttonOrMenuMouseout;
// [END MODIFIED]
// Position the associated drop down menu under the button and
// show it.
x = getPageOffsetLeft(button);
y = getPageOffsetTop(button) + button.offsetHeight;
// For IE, adjust position.
if (browser.isIE) {
x += button.offsetParent.client
y += button.offsetParent.client
}
button.menu.style.left = x + "px";
button.menu.style.top = y + "px";
if (browser.isOP) {
y -= 18;
button.menu.style.top = y + "px";
}
button.menu.style.visibili
// For IE; size, position and show the menu's IFRAME as well.
if (button.menu.iframeEl != null)
{
button.menu.iframeEl.style
button.menu.iframeEl.style
button.menu.iframeEl.style
button.menu.iframeEl.style
button.menu.iframeEl.style
}
}
function resetButton(button) {
// Restore the button's style class.
if (browser.isIE)
{
button.src = "_gfx/" + button.id + "-off.jpg";
}
else
{
var images = button.getElementsByTagNam
for (ti = 0; ti < images.length; ti++)
{
var thisImage = images[ti];
if ((thisImage.src) && (button.id))
{
thisImage.src = "_gfx/" + thisImage.id + "-off.jpg";
}
}
}
removeClassName(button, "menuButtonActive");
// Hide the button's menu, first closing any sub menus.
if (button.menu != null) {
closeSubMenu(button.menu);
button.menu.style.visibili
// For IE, hide menu's IFRAME as well.
if (button.menu.iframeEl != null)
button.menu.iframeEl.style
}
}
//------------------------
// Code to handle the menus and sub menus.
//------------------------
function menuMouseover(event) {
var menu;
// Find the target menu element.
if (browser.isIE)
menu = getContainerWith(window.ev
else
menu = event.currentTarget;
// Close any active sub menu.
if (menu.activeItem != null)
closeSubMenu(menu);
}
function menuItemMouseover(event, menuId) {
var item, menu, x, y;
// Find the target item element and its parent menu element.
if (browser.isIE)
item = getContainerWith(window.ev
else
item = event.currentTarget;
menu = getContainerWith(item, "DIV", "menu");
// Close any active sub menu and mark this one as active.
if (menu.activeItem != null)
closeSubMenu(menu);
menu.activeItem = item;
// Highlight the item element.
item.className += " menuItemHighlight";
// Initialize the sub menu, if not already done.
if (item.subMenu == null) {
item.subMenu = document.getElementById(me
if (item.subMenu.isInitialize
menuInit(item.subMenu);
}
// [MODIFIED] Added for activate/deactivate on mouseover.
// Set mouseout event handler for the sub menu, if not already done.
if (item.subMenu.onmouseout == null)
item.subMenu.onmouseout = buttonOrMenuMouseout;
// [END MODIFIED]
// Get position for submenu based on the menu item.
x = getPageOffsetLeft(item) + item.offsetWidth;
y = getPageOffsetTop(item);
// Adjust position to fit in view.
var maxX, maxY;
if (browser.isIE) {
maxX = Math.max(document.document
(document.documentElement.
maxY = Math.max(document.document
(document.documentElement.
}
if (browser.isOP || browser.isSA) {
maxX = document.documentElement.s
maxY = document.documentElement.s
}
else if (browser.isNS) {
maxX = window.scrollX + window.innerWidth;
maxY = window.scrollY + window.innerHeight;
}
maxX -= item.subMenu.offsetWidth;
maxY -= item.subMenu.offsetHeight;
if (x > maxX)
x = Math.max(0, x - item.offsetWidth - item.subMenu.offsetWidth
+ (menu.offsetWidth - item.offsetWidth));
y = Math.max(0, Math.min(y, maxY));
// Position and show the sub menu.
item.subMenu.style.left = x + "px";
item.subMenu.style.top = y + "px";
// Safari sets the sub-menu too far to the right and too far down - adjust positioning to bring them closer to what they should be
if (browser.isSA) {
x -= 8;
y -= 16;
item.subMenu.style.left = x + "px";
item.subMenu.style.top = y + "px";
}
if (browser.isOP) {
y -= 15;
item.subMenu.style.top = y + "px";
}
item.subMenu.style.visibil
// For IE; size, position and display the menu's IFRAME as well.
if (item.subMenu.iframeEl != null)
{
item.subMenu.iframeEl.styl
item.subMenu.iframeEl.styl
item.subMenu.iframeEl.styl
item.subMenu.iframeEl.styl
item.subMenu.iframeEl.styl
}
// Stop the event from bubbling.
if (browser.isIE)
window.event.cancelBubble = true;
else
event.stopPropagation();
}
function closeSubMenu(menu) {
if (menu == null || menu.activeItem == null)
return;
// Recursively close any sub menus.
if (menu.activeItem.subMenu != null) {
closeSubMenu(menu.activeIt
menu.activeItem.subMenu.st
// For IE, hide the sub menu's IFRAME as well.
if (menu.activeItem.subMenu.i
menu.activeItem.subMenu.if
menu.activeItem.subMenu = null;
}
// Deactivate the active menu item.
removeClassName(menu.activ
menu.activeItem = null;
}
// [MODIFIED] Added for activate/deactivate on mouseover. Handler for mouseout
// event on buttons and menus.
function buttonOrMenuMouseout(event
var el;
// If there is no active button, exit.
if (activeButton == null)
return;
// Find the element the mouse is moving to.
if (browser.isIE)
el = window.event.toElement;
else if (event.relatedTarget != null)
el = (event.relatedTarget.tagNa
// If the element is not part of a menu, reset the active button.
if (getContainerWith(el, "DIV", "menu") == null) {
resetButton(activeButton);
activeButton = null;
}
}
// [END MODIFIED]
//------------------------
// Code to initialize menus.
//------------------------
function menuInit(menu) {
var itemList, spanList;
var textEl, arrowEl;
var itemWidth;
var w, dw;
var i, j;
// For IE, replace arrow characters.
if (browser.isIE) {
menu.style.lineHeight = "2.5ex";
spanList = menu.getElementsByTagName(
for (i = 0; i < spanList.length; i++)
if (hasClassName(spanList[i],
spanList[i].style.fontFami
spanList[i].firstChild.nod
}
}
// Find the width of a menu item.
itemList = menu.getElementsByTagName(
if (itemList.length > 0)
itemWidth = itemList[0].offsetWidth;
else
return;
// For items with arrows, add padding to item text to make the
// arrows flush right.
for (i = 0; i < itemList.length; i++) {
spanList = itemList[i].getElementsByT
textEl = null;
arrowEl = null;
for (j = 0; j < spanList.length; j++) {
if (hasClassName(spanList[j],
textEl = spanList[j];
if (hasClassName(spanList[j],
arrowEl = spanList[j];
}
if (textEl != null && arrowEl != null) {
textEl.style.paddingRight = (itemWidth
- (textEl.offsetWidth + arrowEl.offsetWidth)) + "px";
// For Opera, remove the negative right margin to fix a display bug.
if (browser.isOP)
arrowEl.style.marginRight = "0px";
}
}
// Fix IE hover problem by setting an explicit width on first item of
// the menu.
if (browser.isIE) {
w = itemList[0].offsetWidth;
itemList[0].style.width = w + "px";
dw = itemList[0].offsetWidth - w;
w -= dw;
itemList[0].style.width = w + "px";
}
// Fix the IE display problem (SELECT elements and other windowed controls
// overlaying the menu) by adding an IFRAME under the menu.
if (browser.isIE) {
menu.iframeEl = menu.parentNode.insertBefo
menu.iframeEl.style.displa
menu.iframeEl.style.positi
}
// Mark menu as initialized.
menu.isInitialized = true;
}
//------------------------
// General utility functions.
//------------------------
function getContainerWith(node, tagName, className) {
// Starting with the given node, find the nearest containing element
// with the specified tag name and style class.
while (node != null) {
if (node.tagName != null && node.tagName == tagName &&
hasClassName(node, className))
return node;
node = node.parentNode;
}
return node;
}
function hasClassName(el, name) {
var i, list;
// Return true if the given element currently has the given class
// name.
list = el.className.split(" ");
for (i = 0; i < list.length; i++)
if (list[i] == name)
return true;
return false;
}
function removeClassName(el, name) {
var i, curList, newList;
if (el.className == null)
return;
// Remove the given class name from the element's className property.
newList = new Array();
curList = el.className.split(" ");
for (i = 0; i < curList.length; i++)
if (curList[i] != name)
newList.push(curList[i]);
el.className = newList.join(" ");
}
function getPageOffsetLeft(el) {
var x;
// Return the x coordinate of an element relative to the page.
x = el.offsetLeft;
if (el.offsetParent != null)
x += getPageOffsetLeft(el.offse
return x;
}
function getPageOffsetTop(el) {
var y;
// Return the x coordinate of an element relative to the page.
y = el.offsetTop;
if (el.offsetParent != null)
y += getPageOffsetTop(el.offset
return y;
}
// -->
<!-- FILE#2: menuinit.css -->
function addEvent(elm, evType, fn, useCapture)
{
// addEvent
// cross-browser event handling for IE5+, NS6 and Mozilla
// By Scott Andrew
if (elm.addEventListener)
{
elm.addEventListener(evTyp
return true;
}
else if (elm.attachEvent)
{
var r = elm.attachEvent("on"+evTyp
return r;
}
else
{
// alert("Handler could not be added");
}
}
function removeEvent(elm, evType, fn, useCapture)
{
// removeEvent
// cross-browser event handling for IE5+, NS6 and Mozilla
// By Scott Andrew
if (elm.removeEventListener)
{
elm.removeEventListener(ev
return true;
}
else if (elm.detatchEvent)
{
var r = elm.detachEvent("on"+evTyp
return r;
}
else
{
// alert("Handler could not be removed");
}
}
function menu_init()
{
// Find all divTag with class menubar and assign functions to A and IMG tags
if (!document.getElementsByTa
{
return;
}
var divTag = document.getElementsByTagN
for (di=0;di<divTag.length;di+
{
var thisDiv = divTag[di];
if (((' '+thisDiv.className+' ').indexOf("menuBar") != -1) && (thisDiv.id))
{
menu_makemenu(thisDiv);
}
else
{
if (((' '+thisDiv.className+' ').indexOf("menu") != -1) && (thisDiv.id))
{
menu_makesubmenu(thisDiv);
}
}
}
}
function menu_makemenu(menu)
{
var anchors = menu.getElementsByTagName(
for (i = 0; i < anchors.length; i++)
{
var thisAnchor = anchors[i];
if (((' '+thisAnchor.className+' ').indexOf("menuButton") != -1) && (thisAnchor.id))
{
var images = thisAnchor.getElementsByTa
for (ti = 0; ti < images.length; ti++)
{
var thisImage = images[ti];
if ((thisImage.src) && (thisAnchor.id))
{
thisImage.style.width = (thisImage.width);
thisImage.style.height = (thisImage.height + 0.1);
}
}
if (thisAnchor.id)
{
thisAnchor.onmouseover=fun
buttonMouseover(event, this.id+"menu");
}
thisAnchor.onmouseout=func
buttonOrMenuMouseout(event
}
}
}
}
}
function menu_makesubmenu(menu)
{
if ((!((' '+menu.id+' ').indexOf("submenu") != -1)))
{
menu.onmouseover=function(
menuMouseover(event);
}
}
var anchors = menu.getElementsByTagName(
tagged = 0;
for (si = 0; si < anchors.length; si++)
{
var thisAnchor = anchors[si];
if (((' '+thisAnchor.className+' ').indexOf("menuItem") != -1) && (menu.id))
{
if(thisAnchor.id )
{
var spans = thisAnchor.getElementsByTa
for (sti = 0; sti < spans.length; sti++)
{
var thisSpan = spans[sti];
if (((' '+thisSpan.className+' ').indexOf("menuItemText")
{
thisAnchor.onmouseover=fun
menuItemMouseover(event, this.id+"menu");
}
sti = spans.length;
}
}
}
}
}
}
Open http://www.lancefrisbee.com/testing/dropdown in Firefox to see how it should act, then again in IE - and you'll see what I'm talking about.
Any help would be GREATLY appreciated and rewarded in kind.
Thank you,
Lance
ASKER
Is it WORKING in both, or BROKE in both?
For me, it's on mouseover in IE, not on page load. In MAC IE 5.2, the dropdowns don't work at all. I'm starting to care less and less about MAC IE... Does it EVER work? :)
Thanks for the fast reply. I have to leave the office for a 4:30pm PST meeting, but I'll return afterwards to straighten this out and address any replies/advice I may have here.
Thanks again.
Lance
For me, it's on mouseover in IE, not on page load. In MAC IE 5.2, the dropdowns don't work at all. I'm starting to care less and less about MAC IE... Does it EVER work? :)
Thanks for the fast reply. I have to leave the office for a 4:30pm PST meeting, but I'll return afterwards to straighten this out and address any replies/advice I may have here.
Thanks again.
Lance
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Zvonko, i did not know about this tool it's great ;o) Thanks for this link!
(soory to be out of subject though ;o)
(soory to be out of subject though ;o)
Lance,
If you are tring to pinpoint the location of a javascript error you can try out
http://jsbughunter.com
its a service I have (currently at no charge), you will have to add a piece of code to your page
and then you will be able to see reports of javascript errors that people that surf your page get.
SnowFlake.
If you are tring to pinpoint the location of a javascript error you can try out
http://jsbughunter.com
its a service I have (currently at no charge), you will have to add a piece of code to your page
and then you will be able to see reports of javascript errors that people that surf your page get.
SnowFlake.
ASKER
So everyone is seeing this correctly with no errors? If so... I can live with it being stupid on just my machine... I don't know why that would be. (Wait yes I do... the computers here at work are outdated.) But still, if it is working correctly in IE for PC, that's my main concern. I would just do an alternate-styled navigation, but this client has 50+ pages, theres really no way around a dropdown menu.
Thanks to Zvonko and Snowflake for the page resources... I will check those out.
If any people reading this thread can let me know if this is working in both IE and Firefox with no Javascript errors, that would be excellent.
http://www.lancefrisbee.com/test/dropdown is the URL once again.
I've already heard from Zvonko (thanks)
Thanks again everyone for your input!
Lance
Thanks to Zvonko and Snowflake for the page resources... I will check those out.
If any people reading this thread can let me know if this is working in both IE and Firefox with no Javascript errors, that would be excellent.
http://www.lancefrisbee.com/test/dropdown is the URL once again.
I've already heard from Zvonko (thanks)
Thanks again everyone for your input!
Lance
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you everyone for your replies... it ended up not being an issue as I am on an incredibly outdated machine. Enjoy the points as I was very slow in response. My apologies!
Thanks again,
Lance
Thanks again,
Lance
I see same behavior in IE and FireFox.