一、开篇
在上一篇中介绍了鼠标点击然后弹出菜单的滑动菜单,这一篇介绍鼠标移动弹出菜单的滑动效果。个人认为鼠标移动的这种滑动菜单更复杂一些。
二、原理
再次引用上一篇的图
这种菜单和鼠标点击的菜单又有很大的不一样了,下面说一下我这种菜单是如何工作的:
1、首先滑动这种效果的基本原理在上一篇已经详细说明了,在这里就不多说了;
2、将按钮和菜单以及他们的所有子元素都添加一个menugroup的Attribute,以便和其他元素区别。并且给这些元素还要绑定mouseover和mouseout事件。这些事件的绑定主要是为了让鼠标移出菜单时菜单不马上收回,而是要有一个时延才收回,在收回之前移入菜单那么菜单就不会收回了。总的思路是:凡是鼠标移入menugroup,就不需要时延关闭了。凡是移出menugroup时,则开始时延关闭。
3、还要给按钮单独再添加一个mouseover的事件绑定,主要是用于弹出菜单。
三、代码
注意:这里用到了关于事件的一个简单框架和几个其他函数,具体的可以下载示例后看源文件。 也可以看我之前写的博客文章进行了解。
SlideMenu
function SlideMenu(oBtn,oMenu,sMenuId){
var btn = oBtn;
var menu = oMenu;
if(menu.id == '')
menu.id = sMenuId;
var menuGroup = sMenuId
var isOpened = false;
var timeOutId = null;
//为下拉菜单添加外框
var menuContainer = document.createElement("div");
menu = menu.parentNode.removeChild(menu);
menuContainer.appendChild(menu);
document.body.appendChild(menuContainer);
//设置外框必要的样式
menuContainer.style.display = 'block';
menuContainer.style.visibility = 'visible';
menuContainer.style.overflow = 'hidden';
menuContainer.style.position = 'absolute';
// 设置下拉菜单的样式
menu.style.position = 'absolute';
menu.style.overflow = 'visible';
menu.style.display = 'block';
menu.style.visibility = 'hidden';// 用户既看不到下拉菜单 又可以获取菜单的宽和高
// 获得下拉菜单的宽和高
var menuWidth = menu.offsetWidth;
var menuHeight = menu.offsetHeight;
//设置下拉菜单容器的宽和高
menuContainer.style.width = menuWidth;
menuContainer.style.height = menuHeight;
//关闭菜单
function CloseMenu(){
if(!isOpened)
return;
BufferMove('document.getElementById("' + menu.id + '").style.top',0,-menuHeight,30,1,fnCallback);
function fnCallback(){
menuContainer.style.display = 'none';
isOpened = false;
oEventUtil.addEventHandler(btn,"mouseover",btnMouseOver);
}
}
//凡是属于这个group的都有
function GroupMouseOver(){
clearTimeout(timeOutId);
timeOutId = null;
}
function GroupMouseOut(){
oEvent = oEventUtil.getEvent();
if(oEvent.relatedTarget.getAttribute("menugroup") != menuGroup && timeOutId == null)
timeOutId = setTimeout(CloseMenu,500);
}
//设置下拉菜单的group
function SetGroup(obj){
obj.setAttribute("menugroup",menuGroup);
oEventUtil.addEventHandler(obj,"mouseover",GroupMouseOver);
oEventUtil.addEventHandler(obj,"mouseout",GroupMouseOut);
for(var i=0;i<obj.childNodes.length;i++){
if(obj.childNodes[i].nodeName != "#text")
SetGroup(obj.childNodes[i]);
}
}
SetGroup(btn);
SetGroup(menu);
// 将下拉菜单容器隐藏
menuContainer.style.display = 'none';
var btnMouseOver = function(){
// 如果已经是展开的话 就不做响应
if(isOpened)
return;
// 如果正在展开的过程中 又将鼠标移到btn上的话 就会响应很多次
// 这样就可以限制在展开的过程当中多次响应mouseover
oEventUtil.removeEventHandler(btn,"mouseover",btnMouseOver);
// 将下拉容器设置为可见 此时下拉菜单为display:block;visibility:hidden;
menuContainer.style.display = 'block';
// 设置下拉容器的位置
var pos = GetPosition(btn);
menuContainer.style.left = pos.x + 'px';
menuContainer.style.top = (pos.y + btn.offsetHeight) + 'px';
// 设置下拉菜单的属性
menu.style.left = '0px';
menu.style.top = -menuHeight + 'px';
menu.style.visibility = 'visible';
BufferMove('document.getElementById("' + menu.id + '").style.top',-menuHeight,0,30,1,fnCallback);
function fnCallback(){
isOpened = true;
}
}
oEventUtil.addEventHandler(btn,"mouseover",btnMouseOver);
}
使用方法如下:
window.onload = function(){
new SlideMenu($("btn1"),$("menu1"),"menu1");
}
第一个参数是按钮对象,第二个参数是菜单对象,第三个参数是menugroup的字符串,在同一页面内要唯一。
四、下载
点此下载示例