在web上编写菜单一直是比较头疼的事情,要是有个类直接套用就好了,最近又要做网站了,烦人,要求做的还是多级菜单,唉,废话少说,遇到问题就要解决啊,看代码:
function is(e, handler) {
if (e.type != 'mouseout' && e.type != 'mouseover') return false;
var reltg = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement;
while (reltg && reltg != handler)
reltg = reltg.parentNode;
return (reltg != handler);
}
var menu=function(obj){
var div=document.createElement("div");
div.style.position="absolute";
div.style.left="-1000px";
div.style.top="0px";
div.flag="menu"
document.body.appendChild(div);
div.onmouseout=function(e){
var e=e||window.event;
if(!is(e,this)) return;
e=e.relatedTarget?e.relatedTarget:e.toElement;
if(e.flag!="menu"){
div.style.left="-1000px";
div.style.top="0px"
}
}
function exec(obj,div){
var a;
for(a in obj){
var item=document.createElement("div");
item.flag="menu";
item.style.textAlign="center";
item.innerHTML=typeof(obj[a])=="object"?a:'<a flag="menu" href="'+obj[a]+'">'+a+'</a>';
div.appendChild(item);
if(typeof(obj[a])=="object"){
var idiv=document.createElement("div");
idiv.style.position="absolute"
idiv.flag="menu";
idiv.style.left="-1000px";
idiv.style.top="0px";
item.onmouseover=function(e){
var e=e||window.event;
if(!is(e,this)) return;
e=e.relatedTarget?e.relatedTarget:e.fromElement;
if (e != idiv) {
//alert(this.parentNode.offsetTop + this.offsetTop);
idiv.style.left = this.parentNode.offsetLeft + this.offsetWidth - 1 + "px";
idiv.style.top = this.parentNode.offsetTop + this.offsetTop + "px";
}
if(e.stopPropagation){
e.stopPropagation();
}else{
window.event.cancelable=true;
}
}
item.onmouseout=function(e){
var e=e||window.event;
if(!is(e,this)) return;
e=e.relatedTarget?e.relatedTarget:e.toElement;
if (!(e ==idiv || e.parentNode== idiv || e.parentNode.parentNode==idiv)) {
idiv.style.left = "-1000px";
idiv.style.top = "0px";
}
}
idiv.onmouseout=function(e){
var e=e||window.event;
if(!is(e,this)) return;
e=e.relatedTarget?e.relatedTarget:e.toElement;
if(e.flag!="menu"){
var a=document.getElementsByTagName("*");
for(var i=0;i<a.length;i++){
if(a[i].tagName=="DIV" && a[i].flag=="menu"){
a[i].style.left="-1000px";
a[i].style.top="0px"
}
}
}
if(e.stopPropagation){
e.stopPropagation();
}else{
window.event.cancelable=true;
}
}
document.body.appendChild(idiv);
exec(obj[a],idiv);
}
}
}
exec(obj,div);
this.bind=function(ee,flag){
if(flag=="v"){
ee.onmouseover=function(e){
var e=e||window.event;
var e1=e.relatedTarget?e.relatedTarget:e.fromElement; ;
if (e1 != div) {
div.style.top = ee.getBoundingClientRect().top + ee.offsetHeight-2 + "px";
div.style.left = ee.getBoundingClientRect().left + "px";
}
//alert(div.innerHTML);
}
ee.onmouseout=function(e){
//alert(e);
var e=e||window.event;
var e1=e.relatedTarget?e.relatedTarget:e.toElement;
//alert(e.toElement);
if (e1.flag!="menu") {
div.style.left = "-1000px";
div.style.top = "0px";
}
}
}
}
}
这个的is函数是为了解决ie和ff下的onmouseover和onmouseout问题,保证可以模拟出onmouseenter和onmouseleave的效果,menu留出一个bind方法,用来绑定元素的,下面看示例:
var s=new menu({"adsfsdf":"http://www.baidu.com",
"sasdasd":{"asdasdasd":34,
"eret":3434,
"treter":{"wedqw":4353,
"werew":3453}}
});
s.bind(document.getElementById("w"),"v");
这里用了json数据格式来进行数据传递,比如adsfsdf就是菜单名称,http://www.baidu.com就是链接地址,或者后面跟一个json就是表示下一级菜单,还算比较方便的吧。
当然我这里在ff下实现还有些问题,如有哪有高手看出代码弊端的话,还望指点下小弟。
本人水平有限,代码不妥之处,还望多多指点。