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实现多级下拉框无刷新的联动
Dec 22 Javascript
jquery中加载图片自适应大小主要实现代码
Aug 23 Javascript
javascript 弹出的窗口返回值给父窗口具体实现
Nov 23 Javascript
jquery插件开发之实现md5插件
Mar 17 Javascript
基于casperjs和resemble.js实现一个像素对比服务详解
Jan 10 Javascript
详解webpack多页面配置记录
Jan 22 Javascript
简单了解JavaScript中常见的反模式
Jun 21 Javascript
vue的注意规范之v-if 与 v-for 一起使用教程
Aug 04 Javascript
三步实现ionic3点击退出app程序
Sep 17 Javascript
基于javascript实现贪吃蛇经典小游戏
Apr 10 Javascript
openlayers实现图标拖动获取坐标
Sep 25 Javascript
如何使用RoughViz可视化Vue.js中的草绘图表
Jan 30 Vue.js
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
php引用计数器进行垃圾收集机制介绍
2012/09/19 PHP
php中将html中的br换行符转换为文本输入中的换行符
2013/03/26 PHP
php弹出对话框实现重定向代码
2014/01/23 PHP
php利用smtp类实现电子邮件发送
2015/10/30 PHP
php递归函数怎么用才有效
2018/02/24 PHP
ajax java 实现自动完成功能
2012/12/19 Javascript
jQuery多媒体插件jQuery Media Plugin使用详解
2014/12/19 Javascript
javascript伸缩菜单栏实现代码分享
2015/11/12 Javascript
动态生成的DOM不会触发onclick事件的原因及解决方法
2016/08/06 Javascript
前端程序员必须知道的高性能Javascript知识
2016/08/24 Javascript
Node.js制作简单聊天室
2017/01/12 Javascript
详解bootstrap导航栏.nav与.navbar区别
2017/11/23 Javascript
如何将你的AngularJS1.x应用迁移至React的方法
2018/02/01 Javascript
微信小程序模拟cookie的实现
2018/06/20 Javascript
jQuery实现参数自定义的文字跑马灯效果
2018/08/15 jQuery
vue 使用高德地图vue-amap组件过程解析
2019/09/07 Javascript
layer弹出层倒计时关闭的实现方法
2019/09/27 Javascript
jQuery+PHP+Ajax实现动态数字统计展示功能
2019/12/25 jQuery
JavaScript动态生成表格的示例
2020/11/02 Javascript
python笔记(1) 关于我们应不应该继续学习python
2012/10/24 Python
下载安装setuptool和pip linux安装pip    
2014/01/24 Python
用Python进行一些简单的自然语言处理的教程
2015/03/31 Python
python使用Plotly绘图工具绘制散点图、线形图
2019/04/02 Python
Python从list类型、range()序列简单认识类(class)【可迭代】
2019/05/31 Python
Python优秀开源项目Rich源码解析的流程分析
2020/07/06 Python
在CentOS7下安装Python3教程解析
2020/07/09 Python
Python判断远程服务器上Excel文件是否被人打开的方法
2020/07/13 Python
HTML5实现签到 功能
2018/10/09 HTML / CSS
建筑行业的大学生自我评价
2013/12/08 职场文书
《云房子》教学反思
2014/04/20 职场文书
法定代表人授权委托书范文
2014/09/22 职场文书
2014年英语教研组工作总结
2014/12/06 职场文书
先进工作者个人总结
2015/02/15 职场文书
党员反腐倡廉学习心得体会
2015/08/15 职场文书
Django与数据库交互的实现
2021/06/03 Python
Python干货实战之八音符酱小游戏全过程详解
2021/10/24 Python