Click to See Complete Forum and Search --> : Pull down menu


CreativeMind
03-15-2007, 09:52 AM
Hello, I have a question regarding browser issue. I have created a pull down menu and it looks great in IE6 but not good in Firefox browser. I have attached a sample image to look at and CSS. You will notice that the Firefox browser will not display the blue background. Thanks!

<style>


.hidden, .hidden * {
visibility : hidden;
}

.menu {
position : absolute;
}

.menu .menulabel {
display : block;
padding : 4px 10px;
border-right : 1px solid rgb(0, 0, 150);
}

.menulabel {
font-family : arial;
font-size : 12px;
border-bottom : 1px solid rgb(0, 0, 150);
border-top : 1px solid rgb(100, 100, 220);
color : white;
cursor : pointer;
background : rgb(37, 72, 179);
/* background : url(../ui-images/menu-bg.png); */
text-decoration : none;
}

.menu .menu {
z-index : 10;
}

.menuhover {
background : rgb(100, 100, 220);
}

.foldarrow {
vertical-align : middle;
}

.rightfoldarrow {
position : absolute;
right : 4px;
height : 16px;
width : 16px;
}

.leftfoldarrow {
height : 16px;
width : 16px;
}

.topmenulabel {
background : url(../ui-images/menu-bg.gif);
border-bottom : none;
border-top : none;
height : 17px;
margin-right : 10px;
}

.menutop .menuend {
border-top : 1px solid rgb(100, 100, 220);
}

.menutop img {
height : 5px;
width : 5px;
}

.menubottom img {
height : 5px;
width : 5px;
}

.menuend {
height : 1px;
width : 140px;
}

.menubottom .menuend {
}

.menubottom {
white-space : nowrap;
}

.menutop {
white-space : nowrap;
}

a img {
border : 0px;
}

</style>

WebJoel
03-15-2007, 07:14 PM
I would need to see your entire code, -mostly to see how the <ul> is structured, but right off, it appears and IE is incorrectly expanding the width of the <li> to encompass the anchor, whereas Firefox is probably doing exactly what it was told to do. -The fault is most probably IE doing it wrongly (and looking good whilst doing it).

It's probably not a difficult thing to remedy once the entire code is shown. :)

CreativeMind
03-16-2007, 10:52 AM
Thanks WebJoel for helping. I was not able to paste in the entire code because it was too much texts. I was also not able to atached word doc because it's a large size file. Is there another way to send the entire code to you?

Thanks!

CreativeMind
03-16-2007, 03:20 PM
Thanks WebJoel for helping. Below are javascript for the menu:

var menuWidth = 160;

//function menuInit() {
var topMenu = [];
var unitNum;
for (unitNum = 0; unitNum < menuTree.length && menuTree[unitNum].label != unitName; unitNum++);
if (unitNum == menuTree.length)
topMenu.add(topMenuItem('Unit', 0, menu(menuTree)));
else {
topMenu.add(topMenuItem(unitName, 0, menu(menuTree)));
topMenu.add(topMenuItem(chapterName, menuWidth, menu(menuTree, unitNum)));

if (lessonName) {
var chapterNum;
for (chapterNum = 0; chapterNum < menuTree[unitNum].menu.length && menuTree[unitNum].menu[chapterNum].label != chapterName; chapterNum++);
topMenu.add(topMenuItem(lessonName, menuWidth * 2, menu(menuTree, unitNum, chapterNum)));
}
}

addContent(_('breadcrumb'), topMenu);
//}

function menu(menuTree, submenu) {
if (submenu != undefined && typeof(submenu) == 'number') {
for (var i = 1; i < arguments.length; i++) {
menuTree = menuTree[arguments[i]].menu;
if (!menuTree)
return false;
}
submenu = false;
}

var menuElement = element('div', { className : 'menu hidden' });

if (submenu)
addContent(menuElement,
element('span', { className : 'menutop' },
transparentImage('ui-images/menu-left-top.png', 5, 5),
image('ui-images/menu-bg.gif', { className : 'menuend', height : 4 } ),
transparentImage('ui-images/menu-right-top.png', 5, 5)));

for (var i = 0; i < menuTree.length; i++) {
var item = menuItem(menuTree[i]);
if (i == 0)
item.firstChild.style.borderTop = 'none';
if (i == menuTree.length - 1)
item.firstChild.style.borderBottom = 'none';
addContent(menuElement, item);
}

addContent(menuElement,
element('span', { className : 'menubottom' },
transparentImage('ui-images/menu-left-bottom.png', 5, 5),
image('ui-images/menu-bg.gif', { className : 'menuend' } ),
transparentImage('ui-images/menu-right-bottom.png', 5, 5)));

return menuElement;
}

function menuItem(item) {
var label = link(item.link, item.label,
{ className : 'menulabel',
onmouseover : function() {
this.addClass('menuhover');
},
onmouseout : function() {
this.removeClass('menuhover');
}
} );
var block = element('div', label);

if (item.menu) {
var arrow = foldArrow({ className : 'rightfoldarrow' });
addContent(label, arrow);
var submenu = menu(item.menu, true);
addContent(block,
[ submenu,
{ arrow : arrow,
submenu : submenu,
widthSet : false,
onmouseover : function(e) {
if (!e) e = event;
if (e.fromElement && isSelfOrDescendent(e.fromElement, this))
return;
this.arrow.setState(1);
this.submenu.style.top = (this.offsetTop - 5) + 'px';
this.submenu.style.left = this.offsetWidth + 'px';
this.submenu.show();
if (!this.widthSet) {
var w = this.submenu.offsetWidth + 10;
this.submenu.firstChild.firstChild.nextSibling.style.width = w + 'px';
this.submenu.lastChild.firstChild.nextSibling.style.width = w + 'px';
this.widthSet = true;
}
},
onmouseout : function(e) {
if (!e) e = event;
if (e.toElement && isSelfOrDescendent(e.toElement, this))
return;
this.arrow.setState(0);
this.submenu.hide();
}
}
]);
}

return block;
}

function topMenuItem(label, x, submenu) {
var arrow = foldArrow({ className : 'leftfoldarrow' });
var e = element('span',
{ className : 'topmenulabel menulabel' },
arrow,
' ' + label,
submenu,
{ submenu : submenu,
arrow : arrow,
widthSet : false,
onmouseover : function(e) {
if (!e) e = event;
if (e.fromElement && isSelfOrDescendent(e.fromElement, this))
return;
if(!(submenu == false)) {
this.submenu.style.left = '0px';
this.submenu.style.top = this.offsetHeight + 'px';
this.submenu.style.left = this.offsetLeft + 'px';
this.submenu.show();
if (!this.widthSet) {
var w = this.submenu.offsetWidth + 10;
this.submenu.lastChild.firstChild.nextSibling.style.width = w + 'px';
this.widthSet = true;
}
}
this.arrow.setState(1);
},
onmouseout : function(e) {
if (!e) e = event;
if (e.toElement && isSelfOrDescendent(e.toElement, this))
return;
this.arrow.setState(0);
if(!(submenu == false)) {
this.submenu.hide();
}
}
}
);
return e;
}

function isSelfOrDescendent(testElement, refElement) {
for (;testElement; testElement = testElement.parentNode)
if (testElement == refElement)
return true;
return false;
}

function foldArrow() {
return multiStateImage('ui-images/menu-arrow-right.png', 'ui-images/menu-arrow-down.png',
{ align : 'absmiddle', width : 10, height : 10 },
remainingArgs(arguments, 0));
}

function transparentImage(src, w, h) {
if (isIE6 && src.toLowerCase().indexOf('.png') != -1)
return image('blank.gif',
{ width : w,
height : h,
style : { filter : "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "',sizingMethod='scale')" }
}
);
else
return image(src);
}

CreativeMind
03-16-2007, 04:20 PM
WebJoel, Here are more javascript for you to look at:


var isIE6 = navigator.userAgent.indexOf('MSIE 6') != -1;

/**************************************************************************
* Useful Array methods
*
**************************************************************************/

Array.prototype.indexOf = function(e) {
for (var i = 0; i < this.length; i++)
if (this[i] == e)
return i;
return -1;
}

Array.prototype.contains = function(e) {
return this.indexOf(e) != -1;
}

Array.prototype.remove = function(e) {
var p = this.indexOf(e);
if (p != -1) {
for (; p < this.length - 1; p++)
this[p] = this[p+1];
delete this[p];
this.length = p;
}
return this;
}

Array.prototype.add = function(e) {
this[this.length] = e;
}


/**************************************************************************
* Widget content methods: addContent, clearContent, setContent
*
**************************************************************************/

function addContent(element, content) {
if (!content)
return;
var type = typeof(content);
if (type == 'function')
return;
else if (content instanceof Array)
for (var i = 0; i < content.length; i++)
addContent(element, content[i]);
else if (type != 'object')
element.appendChild(document.createTextNode(content));
else if (content.nodeName)
element.appendChild(content);
else
copyProperties(element, content);
}

function clearContent(element) {
while (element.hasChildNodes())
element.removeChild(element.lastChild);
}

function setContent(element, content) {
clearContent(element);
addContent(element, content);
}

/**************************************************************************
* element(name, { attributes | children })
* creates element with name, attributes and children specified
*
**************************************************************************/
function element(name) {
var e = document.createElement(name);
for (var i = 1; i < arguments.length; i++) {
var arg = arguments[i];
if (!arg)
continue;
addContent(e, arguments[i]);
}
addContent(e, elementMethods);
return e;
}

function copyProperties(to, from) {
for (var p in from) {
if (!to[p] || typeof(to[p]) != 'object' || typeof(from[p]) != 'object') {
to[p] = from[p];
} else {
copyProperties(to[p], from[p]);
}
}
}

/**************************************************************************
* Element class methods: add and remove class names from element class attribute
*
**************************************************************************/
var elementMethods = {
addClass : function(style) {
if (!this.className || this.className.length == 0)
this.className == style;
else if (!this.className.split(/\s+/).contains(style))
this.className += ' ' + style;
},

removeClass : function(style) {
if (this.className && this.className.length > 0)
this.className = this.className.split(/\s+/).remove(style).join(' ');
},

show : function() { this.removeClass('hidden'); },

hide : function() { this.addClass('hidden'); },

left : function() {
var left = 0;
var e = this;
while (e) {
left += e.offsetLeft;
e = e.offsetParent;
}
return left;
},

top : function() {
var top = 0;
var e = this;
while (e) {
top += e.offsetTop;
e = e.offsetParent;
}
return top;
},

right : function() { return this.left() + this.offsetWidth; },

bottom : function() { return this.top() + this.offsetHeight; }
};


/**************************************************************************
* positioned(x, y, z, widget)
* absolutely positions widget at x, y, z
*
**************************************************************************/

function positioned(x, y, widget) {
return element('div',
{ style : { position : 'absolute', 'left' : x + 'px', top : y + 'px' }},
widget);
}


/**************************************************************************
* multiStateImage({ srcPath })
* an img tag which can change state using img.show(n) method
*
**************************************************************************/

function multiStateImage() {
var attrs = { states : [],
setState : function(n) { this.src = this.states[n]; }
};

if (isIE6) {
attrs.onreadystatechange = function() { fixPNG(this); };
attrs.onload = attrs.onreadystatechange;
}

var img = element('img', attrs);

for (var i = 0; i < arguments.length; i++)
if (typeof(arguments[i]) == 'string')
img.states[img.states.length] = arguments[i];
else
addContent(img, arguments[i]);
img.setState(0);
return img;
}

// Utility function which runs fn(item) on all items in list
function forAll(list, fn) {
for (var i = 0; i < list.length; i++)
fn(list[i]);
}

/**************************************************************************
* singleActivated({ widget })
*
*
**************************************************************************/

function singleActivated() {
var elements = [];
for (var i = 0; i < arguments.length; i++) {
elements[i] = arguments[i];
elements[i].deactivateableSiblings = elements;
elements[i]._originalActivate = elements[i].activate;
elements[i].activate = function() {
forAll(this.deactivateableSiblings, function(e) { e.deactivate(); });
this._originalActivate();
};
}
return elements;
}

function remainingArgs(a, n) {
var result = new Array();
var j = 0;
for (var i = n; i < a.length; i++) {
result[j++] = a[i];
}
return result;
}

function image(src) {
var attrs = { src : src };
if (isIE6 && src.indexOf('.png') != -1)
attrs.onload = attrs.onreadystatechange = function() { fixPNG(this); };
return element('img', attrs, remainingArgs(arguments, 1));
}

function link(href) {
return element('a', href ? { href : href } : false, remainingArgs(arguments,1));
}


Let me know if you need more code. I am not able to paste the entire code because it is much code. I will have to paste little at a time.

WebJoel
03-17-2007, 10:56 AM
That's enough code. :o Javascript is not my strongest suit, -I was rather hoping to see an HTML/CSS thing (which you also included). As for 'size of file exceeding WD attachment size', you should get a ZIP-program, ZIP/compress your files as an attachment.

Anyway, that it works for IE6 and poorly for Firefox suggest to me that the CSS or HTML needs work (for, if the javascript works at all, it probably is 100% all-browser being client-side you know).
I will examine the CSS, but would probably need to view the actual HTML (the "<ul><li><a href="etc etc">Link</a></li>....</ul>"> portion. Otherwise, I could only guess at how it is written. ;)

CreativeMind
03-17-2007, 11:47 AM
WebJoel, please see my zip file as an attachment. Thanks and let me know if you are not able to open it. I copied the code and paste within word doc. You can also open with notepad as well.

WebJoel
03-17-2007, 06:37 PM
Wow... I don't even know where to begin looking. All that javascript... :mad: -Not my favorite thing.

Are all these external files required? I haven't made any of them 'absolute path' so haven't seen what they do 'on my offline editor', -but sheez.... that's going to be a few http-requests going on there, eh? :p

Looking again at that image you posted, it almost looks like my first assessment of IE incorrectly-expanding to encompass the elements of text. In the Firefox view, the small variance of width between "Unit B" and "Unit C" might be attributable to the kern difference between the "B" and "C", and Firefox's (presumeably correct behaviour) of wrapping it tightly reveals a minor variation in width...

I think I am not qualified to help with this one :o . Is this 'online' somewhere? If I could get the paths 'absolute', the thing might work on my offline-editor and maybe I can see what you describe...