with a mouseover/out set to the #moo <li>. The script works alright when I mouse over the li, but when I mouse over the link inside the li, it triggers an onmouseout and hides the menu. Is there a workaround for this, or an alternative place to set mouseovers/outs for this kind of menu?
I think I found the problem; I should pad the <a> instead of the <li>...
Yeah, I'm aware of those and I've used them in the past... this menu's going to have between 3 and 4 layers of submenus and suckerfish is a gigantic pain in the ass after that. I was looking to make something more robust and incredibly simple to implement that didn't rely on any specific type of element or the position of the elements on the page. This script works with every set of elements on the page given ids of "mnu_anysection" and "sm_anysection". You create a new menu in the header with "var menu = new Menu('main','about','anysection','variablearguments','submenu','layer2submenu', ... );" then put "menu.setMO();" in your body.onload(), and that's it.
Here's my code, if anyone else wants it:
//menu constructor function Menu() { //create submenus this.sections = null; if (arguments.length > 0) { this.sections = new Array(arguments.length); for (i in arguments) { this.sections[i] = new Submenu(arguments[i]); } } //return section by name this.get = function(sName) { for (i in this.sections) { if (sName == this.sections[i].getName()) return this.sections[i]; } } //hide all sections this.hideAll = function() { for (i in this.sections) { this.sections[i].hide(); } } //show all sections this.showAll = function() { for (i in this.sections) { this.sections[i].show(); } } //set the mouseover functions for the submenus this.setMO = function() { for (i in this.sections) { this.sections[i].setMO(); } } }
//submenu constructor function Submenu(name) { this.name = name; this.opacity = 0.0; // 0.0 is 0%, 1.0 is 100% this.step = 0; //0.05 makes visible, -0.05 makes invisible, 0 stays the same this.timer = null; //set mouseover functions this.setMO = function() { document.getElementById("mnu_"+this.name).onmouseover = function() { menu.hideAll(); menu.get(this.id.substring(4)).show(); } document.getElementById("mnu_"+this.name).onmouseout = function() { menu.hideAll(); menu.get(this.id.substring(4)).hide(); } } //get name function this.getName = function() { return this.name; } //hide submenu this.hide = function() { if (this.opacity <= 0) return; this.step = -0.05; if (this.timer == null) this.timer = setInterval('menu.get("'+this.name+'").update()',10); } //show submenu this.show = function() { if (this.opacity >= 1) return; this.step = 0.05; document.getElementById("sm_"+this.name).style.display="inline"; if (this.timer == null) this.timer = setInterval('menu.get("'+this.name+'").update()',10); } //update function this.update = function() { //if it's done in either direction if ((this.step == -0.05 && this.opacity <= 0) || (this.step == 0.05 && this.opacity >= 1)) { clearInterval(this.timer); this.timer = null; //make it go away when it's done if (this.opacity <= 0) document.getElementById("sm_"+this.name).style.display="none"; //reset the step and exit this.step = 0; return; } this.opacity+=this.step; //apply the thinger var x = document.getElementById("sm_"+this.name); x.style.opacity=this.opacity; x.style.filter='alpha(opacity=' + this.opacity*100 + ')'; x.style.MozOpacity=this.opacity; } }