一、开篇

在上一篇中介绍了鼠标点击然后弹出菜单的滑动菜单,这一篇介绍鼠标移动弹出菜单的滑动效果。个人认为鼠标移动的这种滑动菜单更复杂一些。

二、原理

再次引用上一篇的图

Javascript滑动菜单(二)

 这种菜单和鼠标点击的菜单又有很大的不一样了,下面说一下我这种菜单是如何工作的:

1、首先滑动这种效果的基本原理在上一篇已经详细说明了,在这里就不多说了;

2、将按钮和菜单以及他们的所有子元素都添加一个menugroup的Attribute,以便和其他元素区别。并且给这些元素还要绑定mouseover和mouseout事件。这些事件的绑定主要是为了让鼠标移出菜单时菜单不马上收回,而是要有一个时延才收回,在收回之前移入菜单那么菜单就不会收回了。总的思路是:凡是鼠标移入menugroup,就不需要时延关闭了。凡是移出menugroup时,则开始时延关闭。

3、还要给按钮单独再添加一个mouseover的事件绑定,主要是用于弹出菜单。

三、代码

注意:这里用到了关于事件的一个简单框架和几个其他函数,具体的可以下载示例后看源文件。 也可以看我之前写的博客文章进行了解。

 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的字符串,在同一页面内要唯一。

四、下载

点此下载示例
 

相关文章:

  • 2021-09-09
  • 2021-12-03
  • 2021-07-03
  • 2021-09-06
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-11-29
  • 2022-02-24
  • 2021-09-13
  • 2021-09-25
  • 2022-12-23
  • 2022-03-08
相关资源
相似解决方案