Javascript滑动菜单(一)

一、开篇

在研究CS08的时候,看到后台管理的Dashboard滑动按钮做得很漂亮,于是自己就动手写了一个,在这里与大家分享。菜单展开可以是鼠标点击按钮,也可以是鼠标移动到按钮上,在这里先介绍鼠标点击的这种菜单。

二、原理


基本原理很简单,就是将需要滑动的菜单放在一个overflowhidden的容器里,然后控制菜单相对于容器的top属性,实现下拉的效果。

但是实际上也没这么简单,因为要遇到很多问题,比如容器的大小如何控制、容器如何确定位置、容器应该何时出现(如果容器一直存在,则会挡住容器下面的元素)。这些问题是怎么解决的,在下一部分的代码里会有注释说明。在这里说明一下大概的原理:

1、首先在页面载入时,要给菜单加上一个外框,就是上图中的menuContainer,这个框的作用就是遮挡menu。页面载入后,让menu的visibility为hidden,这时用户看不到菜单,但是我们可以获得menu的长和宽,将这个值赋给menuContainer的长和宽(此时menuContainer的display为block,要不然根本就没法赋值),然后将menuContainer的display设置为none。

 

2、当鼠标点击按钮时,根据按钮的位置来确定下拉菜单的位置,将menuContainer的display设置为block后,就可以控制menu的top属性(menu的position为absolute)实现滑动。

 

3、在滑动的过程当中,不能有按钮的事件或者document关于菜单的事件被注册,这样会影响滑动的过程。所以滑动之前删除注册,滑动结束过后重新注册事件。

 

4、当菜单展开的时候,点击按钮时菜单会收回,这里巧妙的用到了事件的冒泡。菜单展开的时候,根据if(isOpened)return;这一句来看,就像点击按钮不起作用一样,点击按钮的事件会冒泡到document,而此时document恰好注册有关闭菜单的方法,从而实现了再次点击按钮关闭菜单的目的。

三、代码

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

ContractedBlock.gifSlideMenu

ExpandedBlockStart.gif
function SlideMenu(oBtn,oMenu){
    
var btn = oBtn;
    
var menu = oMenu;
    
var isOpened = false;
    
//为下拉菜单添加外框
    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;
    
    
// 将下拉菜单容器隐藏
    menuContainer.style.display = 'none';
    
    
var btnClick = function(){
        
// 如果已经是展开的话 就不做响应
        // 而是通过事件冒泡转交给document的click处理
        // 这是会关闭菜单
        if(isOpened)
            
return;
        
// 如果正在展开的过程中 又点击了按钮的话 就会响应很多次
        // 这样就可以限制在展开的过程当中多次点击按钮
        btn.onclick = null;
        
// 将下拉容器设置为可见 此时下拉菜单为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(){
            oEventUtil.addEventHandler(document,
"click",docClick);
            btn.onclick 
= btnClick;
            isOpened 
= true;
        }
    }
    btn.onclick 
= btnClick;
    
var docClick = function(){
        oEvent  
= oEventUtil.getEvent();
        
//防止右键点击
        if(oEvent.button == 2)
            
return;
        oEventUtil.removeEventHandler(document,
"click",docClick);
        BufferMove(
'document.getElementById("' + menu.id + '").style.top',0,-menuHeight,30,1,fnCallback);
        
function fnCallback(){
            menuContainer.style.display 
= 'none';
            isOpened 
= false;
        }
    }
}

      这是菜单类的主要代码,下面是使用方法

window.onload  =   function (){
    
new  SlideMenu($( " btn1 " ),$( " menu1 " ));
}

      即在实例化时传入两个对象到构造函数,前一个参数是菜单按钮对象,后一个参数是需要展开的菜单的对象。

四、下载

      点此下载示例

转载于:https://www.cnblogs.com/LongWay/archive/2008/09/04/1283488.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值