一个多级菜单
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>meun.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=GB18030"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> <script type="text/javascript"> /** *根据标签的类型和名称获取元素 *tagType 标签的类型,比如TD、INPUT、SPAN等 *eleName 标签元素对应的name属性 * **/ function getElmentsByName(tagType, eleName) { var arr = []; if(tagType==""){ alert("Please Input tagType Attribute."); }; var tags = document.getElementsByTagName(tagType); if(eleName==""){ alert("Please Input eleName Attribute."); }; for(var i=0; i<tags.length; i++){ if(tags[i].getAttribute("name")==eleName){ arr.push(tags[i]); } } return arr; } /** 根据元素的ID获取元素 **/ function $(id) { return "string" == typeof id ? document.getElementById(id) : id; } /** 属性复制 **/ var Extend = function(destination, source) { for (var property in source) { destination[property] = source[property]; } return destination; } /** * *给对象绑定事件 *oTarget 目标对象 *sEventType 事件类型 *fnHandler 调用函数 * **/ function addEventHandler(oTarget, sEventType, fnHandler) { if (oTarget.addEventListener) { oTarget.addEventListener(sEventType, fnHandler, false); } else if (oTarget.attachEvent) { oTarget.attachEvent("on" + sEventType, fnHandler); } else { oTarget["on" + sEventType] = fnHandler; } }; /** 调用对象绑定 **/ var Bind = function(object, fun) { var args = Array.prototype.slice.call(arguments).slice(2); return function() { return fun.apply(object, args.concat(Array.prototype.slice.call(arguments))); } } /** 获取元素的绝对X坐标**/ function getElementLeft(element){ var actualLeft = element.offsetLeft; var current = element.offsetParent; while (current !== null){ actualLeft += current.offsetLeft; current = current.offsetParent; } return actualLeft; } /** 获取元素的绝对Y坐标**/ function getElementTop(element){ var actualTop = element.offsetTop; var current = element.offsetParent; while (current !== null){ actualTop += current.offsetTop; current = current.offsetParent; } return actualTop; } /**a元素是否等于或者包含b元素 **/ function ifContains(a, b){ if(a.contains ? a.contains(b) || a == b : a.compareDocumentPosition(b) & 16) return true; return false; } /** 获取对象的属性值 **/ function attr(o,attribute){ return o.getAttribute(attribute); } Object.extend = function(destination, source) { for (var property in source) { destination[property] = source[property]; } return destination; } /** For 循环 **/ function Each(list, fun){ for (var i = 0, len = list.length; i < len; i++) { fun(list[i], i); } }; function Event(e){ var oEvent = document.all ? window.event : e; if (document.all) { if(oEvent.type == "mouseout") { oEvent.relatedTarget = oEvent.toElement; }else if(oEvent.type == "mouseover") { oEvent.relatedTarget = oEvent.fromElement; } oEvent.stopPropagation = function() { this.cancelBubble = true; } } return oEvent; } var Class = { create: function() { return function() { this.Initialize.apply(this, arguments); } } } var MeunUtil = Class.create(); MeunUtil.prototype = { Initialize: function(options){//初始化 var _this = this; this.SetOptions(options); this.topTagType = this.options.topTagType; this.topTagName = this.options.topTagName; this.topOnClass = this.options.topOnClass; this.topOffClass = this.options.topOffClass; this.topMeuns = getElmentsByName(this.topTagType, this.topTagName); this.relativeAttrName = this.options.relativeAttrName; this.childOnClass = this.options.childOnClass; this.childOffClass = this.options.childOffClass; Each(this.topMeuns,function(o){_this.HoverTopMeun(o);});//处理所有的菜单 }, SetOptions: function(options){ //初始化参数 this.options={ topTagName: "topMeun", //topMeun的class属性 topTagType: "td", //topMeun的标签类型 topOnClass: "", //顶级标签获取焦点样式 topOffClass: "", //顶级标签失去焦点样式 relativeAttrName: "childMeun", //指示下级标签的属性名称 childTagType: "", //下级标签的属性名称 childOnClass: "", //下级标签得到焦点时的样式 childOffClass: "" //下级标签失去焦点时的样式 } Object.extend(this.options, options || {}); }, HoverTopMeun: function(topMeun){ var _this = this; var cId = attr(topMeun, _this.relativeAttrName); var child = $(cId); if(!child) return; child.pNode = topMeun; addEventHandler(topMeun, "mouseover", function(){ topMeun.className = _this.topOnClass;//top的css样式设置 child.className = _this.childOnClass;//child的css样式设置 child.style.top = getElementTop(topMeun) + topMeun.clientHeight;//child的top坐标设置 child.style.left = getElementLeft(topMeun);//child的left坐标设置 }); addEventHandler(topMeun, "mouseout", function(e){ var event = Event(e); var toElement = event.relatedTarget;//鼠标移动后的所在的对象 var contains = ifContains(child, toElement); if(!contains){//如果不包含,则说明已经移出去了 topMeun.className = _this.topOffClass; child.className = _this.childOffClass; } }); var spans = child.getElementsByTagName("span"); Each(spans,function(o){ o.pNode = child;//记录当前元素所在的容器 _this.showChildItem(o); }); }, showChildItem: function(pItem){ var _this = this; var cContainerId = attr(pItem, _this.relativeAttrName); var cContainer = $(cContainerId); if(cContainer) cContainer.pNode = pItem; addEventHandler(pItem, "mouseover", function(){ pItem.style.backgroundColor = "yellow"; if(!cContainer) return; var cItems = cContainer.getElementsByTagName("span"); cContainer.className = _this.childOnClass; cContainer.style.top = getElementTop(pItem);//cContainer的top坐标设置 cContainer.style.left = getElementLeft(pItem) + pItem.clientWidth;//cContainer的left坐标设置 }); addEventHandler(pItem, "mouseout", function(e){ var event = Event(e); var toElement = event.relatedTarget;//鼠标移动后的所在的对象 if(cContainer && ifContains(cContainer, toElement)){//如果有子元素,并且移到了字元素块里 return; } if(cContainer) cContainer.className = _this.childOffClass;//隐藏子元素 if(ifContains(pItem.pNode, toElement) || pItem.pNode.pNode==toElement){//移动到了包含其它元素里||父亲元素 pItem.style.backgroundColor = "#CC5500"; }else if(pItem.pNode.pNode && pItem.pNode.pNode.pNode && ifContains(pItem.pNode.pNode.pNode, toElement)){//移动到了父亲容器 pItem.style.backgroundColor = "#CC5500"; pItem.pNode.className = _this.childOffClass; pItem.pNode.pNode.style.backgroundColor = "#CC5500"; }else {//完全移出去了 pItem.style.backgroundColor = "#CC5500"; var cur = pItem.pNode; while(cur){ if(!attr(cur, _this.relativeAttrName)){ cur.className = _this.childOffClass; }else { if(cur.pNode){ cur.style.backgroundColor = "#CC5500"; }else {//如果已经没有父亲元素,则为最上级,css样式不一样 cur.className = _this.topOffClass; } } cur = cur.pNode; } } }); if(!cContainer) return; var spans = cContainer.getElementsByTagName("span"); var _arguments = arguments; Each(spans,function(o){ o.pNode = cContainer;//记录当前元素所在的容器 _arguments.callee.call(_this, o); }); } }; </script> <style type="text/css"> .mainMeunOff{ border: 2px solid #999999; padding: 5px 15px; background-color: #CC0000; width: 100px; width: 96px\9; /**For IE, contains padding**/ text-align: center; } .mainMeunOn{ border: 2px solid #999999; padding: 5px 15px; background-color: #CCEEEE; width: 100px; width: 96px\9; /**For IE, contains padding**/ text-align: center; cursor: pointer; } .item_off{ position: absolute; visibility:hidden; line-height: 20px; } .item_on{ position: absolute; visibility:visible; line-height: 20px; } .item_off span{ background-color: #CC5500; border: 2px solid #999999; display:block; width: 100px; width: 130px\9; /**For IE, contains padding**/ padding: 5px 15px; } .item_on span{ background-color: #CC5500; border: 2px solid #999999; display:block; width: 100px; width: 130px\9; /**For IE, contains padding**/ padding: 5px 15px; } </style> </head> <body style="text-align: center;margin: 50px 100px;" > <table > <tr> <td class="mainMeunOff" name="topMeun" childMeun="cItem_1">菜单一</td> <td class="mainMeunOff" name="topMeun" childMeun="cItem_2">菜单二</td> <td class="mainMeunOff" name="topMeun" childMeun="cItem_3">菜单三</td> <td class="mainMeunOff" name="topMeun"childMeun="cItem_4">菜单四</td> </tr> </table> <div class="item_off" id="cItem_1"> <span>Item 1_1</span> <span childMeun="cItem_1_2">Item 1_2 —></span> <span childMeun="cItem_1_3">Item 1_3 -></span> <span>Item 1_4</span> </div> <div class="item_off" id="cItem_2"> <span>Item 2_1</span> <span childMeun="cItem_2_1">Item 2_2 -></span> <span>Item 2_3</a></span> <span>Item 2_4</span> </div> <div class="item_off" id="cItem_3"> <span>Item 3_1</span> <span>Item 3_2</span> <span>Item 3_3</span> <span>Item 3_4</span> </div> <div class="item_off" id="cItem_4"> <span>Item 4_1</span> <span>Item 4_2</span> <span>Item 4_3</span> <span>Item 4_4</span> </div> <div class="item_off" id="cItem_1_2"> <span>Item 1_2_1</span> <span>Item 1_2_2</span> <span>Item 1_2_3</span> <span>Item 1_2_4</span> </div> <div class="item_off" id="cItem_1_3"> <span>Fun 1_2_1</span> <span>Item 1_3_2</span> </div> <div class="item_off" id="cItem_2_1"> <span childMeun="cItem_2_1_1">Java_boy -></span> <span>Item 2_1_2</span> </div> <div class="item_off" id="cItem_2_1_1"> <span>Item Jack</span> <span>Item Frame</span> <span>Item Sina</span> <span>Item World</span> <span childMeun="cItem_dw">Item Baidu-></span> <span>Item Google</span> </div> <div class="item_off" id="cItem_dw"> <span>Item Daiwei</span> <span>Item Shan</span> </div> <div> <span id="msg"></span> </div> <script> new MeunUtil({ childTagType:"span", childOffClass:"item_off", childOnClass:"item_on", topOffClass:"mainMeunOff", topOnClass:"mainMeunOn" }); </script> </body> </html>