要在点击其他元素时隐藏菜单或者说特定的元素,首先要做到的是检查用户是否点击其他元素。
网上通常的做法是关联$(document)的点击事件。不过这样需要处理冒泡,而且用户在任何时候按键,都会触发事件,虽然处理得好的代码可以合适地安排冒泡与缺省事件动作,但毕竟麻烦,让人放心不下以及影响性能(C程序员的职业病出来了)。
其实要解决这个问题很简单,只需要换个思路:在显示弹出菜单/元素时,建立一个覆盖全屏/全文档的透明元素。用户点击任何非弹出菜单的位置,实际上都是点击到这个元素,于是只需要关联该元素的点击事件就行了,在点击事件中隐藏菜单,再删除自己。一切OK!而且不需要长期关联一个大多数时候都用不着的全局事件,对性能和可靠性都有帮助。
代码如下:
$.fn.closeMenu=function() //用于执行当用户点击菜单执行操作之后关闭弹出菜单的动作
{
$(this).prev().remove();
$(this).hide();
};
$.fn.menu=function()
{
var This=$(this);
This.find("li").unbind("click").on("click",MenuFunc);
var mask="<div style='position:fixed;left:0;top:0;width:"+$(window).width()+"px;height:"+$(window).height()+"px;' οnclick='$(this).next().hide();$(this).remove()'></div>";
This.before(mask);
This.show();
This.children().show();
This.find("li").find("ul").hide();
This.find("li").each(function()
{
if($(this).children("ul").length)
{
$(this).addClass("hasChild");
}
});
function MenuFunc(e)
{
var event = e || window.event;
var Target=$(event.target);
if(Target[0].tagName=="LI")
{
if(Target.children("ul").length)
{
if(Target.hasClass("active"))
{
Target.removeClass("active");
Target.children("ul").animate({height:'toggle'},200);//子菜单动画效果
}
else
{
Target.siblings().each(function()
{
if($(this).hasClass("active"))
{
$(this).removeClass("active");
$(this).children("ul").animate({height:'toggle'},200);
}
});
Target.addClass("active");
Target.children("ul").animate({height:'toggle'},200);
}
}
return false;
}
}
};