XP折叠菜单&仿QQ2006菜单


Posted in Javascript onDecember 16, 2006

特性:

更好的外观:在菜单标题上添加了图标。
更好的动作:实现了菜单的滑入,滑出效果。
更易的使用:添加了许多注释,方便使用。

当然还存在一些没有发现的问题。盼望大家指教:)
实现折叠式动态改变style.height的值 这样不是很专业:) 不过很像了!

100%的原装winXP折叠菜单的外观!如果不一样您提出来我改。
(qq2006 在点击的时候还有一些抖动。)

先看图最新添加了 qq2006 的外观
XP折叠菜单&仿QQ2006菜单XP折叠菜单&仿QQ2006菜单
测试网页的地址:navbar.htm
详细网址:http://lxbzj.com/showartical.asp?N_id=156
下载:http://lxbzj.com/upload/200604/menu.zip
新版本还在制作中。。。(更新的js在19层)
这里是2006-04-13日修改过的js
-不再需要在每一个<a>里面添加 onclick 和 onkeypress 了 这样 网页和js 进一步的分离
-定义了一个menu类 负责将事件添加到每一个 菜单里面
-修改了onkeypress
-添加interval处理
-添加了一个收起的加速度(不过不是很明显)
-添加了Navbar对象,实现在一组menu中只有一个能打开
-新js 不断更新中。。。

+-navbar.js中的代码:

// JavaScript Document 
/*======================================== 
*        文件名:        navbar.js 
*        编  码: Utf-8 
*        功  能:实现菜单折叠的javaScript 
*        作  者:雷晓宝 
*        版  本: 2.3 
*        时  间:2006-03-07 
===========================================*/ 
//========================定义menu类==================; 
function Menu(head,child,dir,speed,init_state,ext_on,ext_off) 
{ 
    this.head = document.getElementById(head);//菜单头 
    this.body = document.getElementById(child);//菜单体 
    this.direction = dir;//菜单收起的方向 
    this.speed = speed;//速度 
    this.ext_on = ext_on;//扩展菜单展开调用 
    this.ext_off = ext_off;//扩展菜单收起调用 
    this.init_state = init_state;//设置菜单的初始状态 true/false 
    this.a = 10;//加速度 
//私用变量; 
    this._interval = false; 
    this._last_state = false; 
    this._size = false; 
    this._temp = false; 
    this._js = false; 
    this._div = false; 
    this._parent = false; 
    this._parent_control = false; 
    var self = this; 
    var temp = new Array(null,null);//temp[0]用来给_off()用,temp[1]用来给_on()用 //=============================方法============================= 
//点击事件处理 
    this.click = function(e) 
    { 
        if (self._parent_control) 
        { 
            self._parent._control(self); 
            return false; 
        } 
        else 
        { 
            Interval.clear(self._interval); 
            if (self._last_state == false) 
            { 
                self._on(); 
                return false; 
            } 
            else 
            { 
                self._off(); 
                return false; 
            } 
        } 
    } 
//初始化 
    this.init = function() 
    { 
        this.head.onclick = this.click; 
        this.head.onkeypress = function(e) 
        { 
            e||(e=window.event); 
            if (!(e.keyCode ==32 || e.keyCode == 0))return; 
            //alert(':)'); 
            self.click(); 
        } 
        for(var i=0;i<this.body.childNodes.length;i++) 
        { 
            if (this.body.childNodes[i].nodeType==1) 
            { 
                this._div=this.body.childNodes[i]; 
                break; 
            } 
        } 
        if (parseInt(this.body.style.height))//this.body.style.getPropertyCSSValue('height')this.body.currentStyle.height 
        { 
            this._size = parseInt(this.body.style.height); 
        } 
        else 
        { 
            this._size = this._div.offsetHeight; 
        } 
        switch (this.init_state) 
        { 
            case true: 
                if (this.body.style.display == 'none') 
                { 
                    //this._last_state = false; 
                    this._on(); 
                } 
                else 
                { 
                    this._last_state = true; 
                } 
                break; 
            default://case false: 
                if (this.body.style.display !='none') 
                { 
                    this._last_state = true; 
                    this._off(); 
                } 
                break; 
        } 
    } 
//展开菜单 
    this._on = function() 
    { 
        if (self._last_state == false) 
        { 
            self._last_state = true; 
            self.body.style.display=""; 
            temp[1] = self.a?2*parseInt(Math.sqrt(self.a*self._size))+1:self._size/5; 
            if (isNaN(parseInt(self.body.style.height)))self.body.style.height="0px"; 
            if (self.ext_on) 
            { 
                self.ext_on(self.head,self.body) 
            } 
            self._interval = Interval.set(self._action_on,speed); 
        } 
        //setTimeout('slowon("'+self.body.id+'")',5) 
    } 
//收起菜单 
    this._off = function() 
    { 
        if (self._last_state == true) 
        { 
            self._last_state = false; 
            //if (temp[0] == null) 
            //{ 
                temp[0]=self.a?2*parseInt(Math.sqrt(self.a*self._size))+1:self._size/5;; 
            //} 
            if(isNaN(parseInt(self.body.style.height)))self.body.style.height = self._size+'px'; 
            if (self.ext_off) 
            { 
                self.ext_off(self.head,self.body) 
            } 
            self._interval = Interval.set(self._action_off,this.speed); 
        } 
    } 
//以下处理滑动 
    this._action_on = function() 
    { 
        if (parseInt(self.body.style.height)+temp[1]>self._size) 
        { 
            self.body.style.height = self._size+'px'; 
            Interval.clear(self._interval); 
        } 
        else 
        { 
        self.body.style.height = parseInt(self.body.style.height)+temp[1]+'px'; 
        temp[1] +=self.a; 
        } 
    } 
    this._action_off = function() 
    { 
        if(parseInt(self.body.style.height)-temp[0]<0) 
        { 
            Interval.clear(self._interval); 
            self.body.style.display = "none"; 
        } 
        else 
        { 
            self.body.style.height = parseInt(self.body.style.height)-temp[0]+'px'; 
            temp[0]-=self.a; 
        } 
    } 
} 
//meanu类结束 
//====================定义Navbar类,用来管理一组menu集合=============================== 
function navbar(dir,a,speed,ext_on,ext_off) 
{ 
    this.open_only_one = true;//这组menu在任何时刻是否只有一个在开启,true/false 
    this.dir = dir;//menu组的公共方向,既然是一组menu它们应该有相同的方向吧? 
    this.a =a;//menu公共加速度 
    this.speed =speed;//公共速度 
    this.ext_on = ext_on;//公共扩展打开函数调用 
    this.ext_off = ext_off;//公共的扩展收起函数调用 
    this.menu_item = new Array();//menu组 
    this._openning;//如果只允许打开一个菜单,这个就会记录当前打开的菜单 
    this.open_all = function()// 
    { 
    }; 
    this.add = function (head,body)//添加menu的函数 
    { 
        var temp = new Menu(head,body,this.dir,this.speed,this.ext_on,this.ext_off); 
        this.menu_item.push(temp); 
    }; 
    this.init = function ()//Navbar的初始化函数,必须在add完成后调用 
    { 
        if(this.open_only_one == true) 
        {//如果只允许一个打开,那么仅仅设置菜单组的第一个菜单为打开状态 
            if (this.menu_item.length>0) 
            { 
                with(this.menu_item[0]) 
                { 
                    init_state = true; 
                    _parent = this;//设置menu的父亲为这个Navbar 
                    _parent_control = true;//设置父亲来控制菜单 
                    init(); 
                } 
                this._openning = this.menu_item[0]; 
            } 
            for(var i = 1; i<this.menu_item.length;i++) 
            {//设置出第一个外的其他菜单为关闭,同时设置好其他参数 
                with(this.menu_item[i]) 
                { 
                    init_state = false; 
                    _parent = this; 
                    init(); 
                    _parent_control = true; 
                } 
            } 
        } 
        else 
        {//如果open_only_one == false 那么仅仅初始化菜单 
            for(var i = 0;i<this.menu_item.length;i++) 
            { 
                this.menu_item.init(); 
            } 
        } 
    }; 
//额外添加的父亲控制函数 
    this._control = function(child) 
    { 
        var self =child; 
        Interval.clear(self._interval); 
        if (self._last_state == false) 
        { 
            if (typeof(self._parent._openning) == 'object') 
                { 
                    self._parent._openning._off(); 
                    self._parent._openning = self; 
                } 
            self._on(); 
            return false; 
        } 
        else 
        { 
            //self._off(); 
            return false; 
        } 
    } 
}//Navbar类结束 

//===============================interval 处理============================= 
//注意:_stack 只有20个 
//扩充时必须赋初值1-n 
Interval= 
{ 
    length:20, 
    _action : new Array(length), 
    _stack : new Array(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19), 
    _interval : Array(length), 
    _timeout: new Array(length), 
    //for(var i=0;i<_action.length;i++)stack.push(i);, 
    set:function(action_function,speed,time_out) 
    { 
        time_out = time_out?time_out:15000;//默认的interval超时为15000秒,如果不需要设置超时,那么将下面的setTimeout 那移行注释掉;  
        var p = Interval._stack.pop(); 
        if(p) 
        { 
            Interval._action[p] = action_function; 
            Interval._interval[p]=setInterval('if(Interval._action['+p+'])Interval._action['+p+']();',speed);//这里的重复执行函数不能写成'Interval._action['+p+']'因为很可能Interval.clear以后,还有一次没有执行完毕,于是就产生了一次错误 
            Interval._timeout[p] = setTimeout('Interval.clear('+p+')',time_out);//这行设置interval超时,如果不需要可注释掉; 
            return p; 
        } 
    }, 
    clear:function(p) 
    { 
        if (Interval._action[p]) 
        { 
            clearInterval(Interval._interval[p]); 
            clearTimeout(Interval._timeout[p]);//这行清除interval超时,如果没有设置超时可注释掉; 
            Interval._action[p] = ""; 
            Interval._stack.push(p); 
        } 
    } 
} 
//Interval 处理结束
Javascript 相关文章推荐
jquery文档操作wrap()方法实例简述
Jan 10 Javascript
js全选实现和判断是否有复选框选中的方法
Feb 17 Javascript
jquery+easeing实现仿flash的载入动画
Mar 10 Javascript
在 Express 中使用模板引擎
Dec 10 Javascript
Easyui 之 Treegrid 笔记
Apr 29 Javascript
Javascript中常见的逻辑题和解决方法
Sep 17 Javascript
js中new一个对象的过程
Feb 20 Javascript
在node.js中怎么屏蔽掉favicon.ico的请求
Mar 01 Javascript
js学习总结_轮播图之渐隐渐现版(实例讲解)
Jul 17 Javascript
JavaScript事件冒泡与事件捕获实例分析
Aug 01 Javascript
微信小程序使用echarts获取数据并生成折线图
Oct 16 Javascript
javascript+css实现进度条效果
Mar 25 Javascript
prototype 1.5相关知识及他人笔记
Dec 16 #Javascript
飞鱼(shqlsl) javascript作品集
Dec 16 #Javascript
XHTML-Strict 内允许出现的标签
Dec 11 #Javascript
JS的IE和Firefox兼容性集锦
Dec 11 #Javascript
不错的新闻标题颜色效果
Dec 10 #Javascript
用脚本调用样式的几种方法
Dec 09 #Javascript
用js计算页面执行时间的函数
Dec 07 #Javascript
You might like
excellent!――ASCII Art(由目标图象生成ascii)
2007/02/20 PHP
ThinkPHP自动转义存储富文本编辑器内容导致读取出错的解决方法
2014/08/08 PHP
Fedora下安装php Redis扩展笔记
2014/09/03 PHP
mac下多个php版本快速切换的方法
2016/10/09 PHP
Javascript优化技巧(文件瘦身篇)
2008/01/28 Javascript
理解Javascript_10_对象模型
2010/10/16 Javascript
用jquery和json从后台获得数据集的代码
2011/11/07 Javascript
基于JavaScript自定义构造函数的详解说明
2013/04/24 Javascript
JavaScript AJAX之惰性载入函数
2014/08/27 Javascript
JS实现仿QQ聊天窗口抖动特效
2015/05/10 Javascript
基于dropdown.js实现的两款美观大气的二级导航菜单
2015/09/02 Javascript
Bootstrap每天必学之滚动监听
2016/03/16 Javascript
ECHO.js 纯javascript轻量级延迟加载的实例代码
2016/05/24 Javascript
AngularJS  双向数据绑定详解简单实例
2016/10/20 Javascript
微信小程序 input输入框控件详解及实例(多种示例)
2016/12/14 Javascript
完美实现js焦点轮播效果(二)(图片可滚动)
2017/03/07 Javascript
footer定位页面底部(代码分享)
2017/03/07 Javascript
vue学习笔记之指令v-text &amp;&amp; v-html &amp;&amp; v-bind详解
2017/05/12 Javascript
JS倒计时实例_天时分秒
2017/08/22 Javascript
vue-router中的hash和history两种模式的区别
2018/07/17 Javascript
Vue组件中的data必须是一个function的原因浅析
2018/09/03 Javascript
tracking.js页面人脸识别插件使用方法
2020/04/16 Javascript
PYTHON基础-时间日期处理小结
2018/05/05 Python
python计算日期之间的放假日期
2018/06/05 Python
tensorflow的计算图总结
2020/01/12 Python
Python各种扩展名区别点整理
2020/02/27 Python
Python网络爬虫信息提取mooc代码实例
2020/03/06 Python
python 贪心算法的实现
2020/09/18 Python
完美解决Pycharm中matplotlib画图中文乱码问题
2021/01/11 Python
css3动画事件—webkitAnimationEnd与计时器time事件
2013/01/31 HTML / CSS
社区活动总结报告
2014/05/05 职场文书
校园文明标语
2014/06/13 职场文书
2014年度思想工作总结
2014/11/27 职场文书
个人工作能力自我评价
2015/03/05 职场文书
缅怀先烈主题班会
2015/08/14 职场文书
优秀员工演讲稿
2019/06/21 职场文书