打印

看我做的XP折叠菜单&仿QQ2006菜单(不像您k我!)

特性:

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

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

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

先看图最新添加了 qq2006 的外观

测试网页的地址:navbar.htm
详细网址:http://lxbzj.com/showartical.asp?N_id=156
下载:http://lxbzj.com/upload/200604/menu.zip
新版本还在制作中。。。(更新的js在19层)

[ 本帖最后由 mickeyboy 于 2006-9-29 10:37 编辑 ]
本帖最近评分记录
无限级算法thread-2780498-1-6.html 2780498-1-1.html

看我做的XP折叠菜单(不像您k我!)

挺不错的效果,而且还支持FF,赞一个

最好能在这里说说代码和制作心得,教教其他人

看我做的XP折叠菜单(不像您k我!)

明天就把 制作过程放上来。。。
无限级算法thread-2780498-1-6.html 2780498-1-1.html

看我做的XP折叠菜单(不像您k我!)

为什么有广告?我汗~```
『我的水客厅,记录曾经经历过的,酝酿即将经历的……』
『织梦者2号群:8606484 插画爱好者2号群:6641795』

TOP

还在为头像烦恼?还在为不能关注好友动态烦忧?快来蓝色理想家园吧!

看我做的XP折叠菜单(不像您k我!)

支持!要看制作过程!

TOP

看我做的XP折叠菜单(不像您k我!)

不错。期待制作过程
活着为了什么?

TOP

看我做的XP折叠菜单(不像您k我!)

挺好的,希望楼主把这个制作过程贴出来。最好附有代码,供我们这些菜鸟研究学习
功名事了,不待老僧招。

TOP

看我做的XP折叠菜单(不像您k我!)

效果做得好!
三人行,必有我师!

TOP

看我做的XP折叠菜单(不像您k我!)

强烈要求过程

TOP

看我做的XP折叠菜单(不像您k我!)

我也等哈.
眼睛

TOP

看我做的XP折叠菜单(不像您k我!)

很不错,等到制作过程

TOP

看我做的XP折叠菜单(不像您k我!)

在线等教程ing。。。。
失败只有一种,就是半途而废!

TOP

看我做的XP折叠菜单(不像您k我!)

效果不错,不过在速度上有点慢。
不知道能不能加快菜单的显示速度
态度决定一切 电影下载

TOP

看我做的XP折叠菜单(不像您k我!)

<script language="JavaScript" type="text/JavaScript">
var sp=12;/*滑动的速度,单位是像素,只填写数字*/

/*==============
实现开关菜单的函数
=================*/
function onoff(taga)
{
var hd=taga.parentNode;
var menu = document.getElementById(hd.id+"_child");
if (menu.style.display =="none"){
taga.className= "on";
menu.style.display="";
setTimeout("slowon(\""+menu.id+"\")",5);/*hda1.style.display="none";*/}
else {
/*menu.style.height="10px";*/
/*menu.style.display="none";*/
taga.className= "off";
setTimeout("slowoff(\""+menu.id+"\")",10);
/*hda1.style.display="";*/}
}
/*================
实现菜单滑动的函数
=================*/
function slowoff(id){/*这个实现菜单收起*/
id=document.getElementById(id);
var h = parseInt(id.style.height);
if(isNaN(h))h= id.offsetHeight;
/*if (h>0){
*/
if(h-sp>0){id.style.height=(h-sp)+"px";
setTimeout("slowoff(\""+id.id+"\")",5);/*}else */}
else{id.style.height="0px";
id.style.display="none";
/*id.style.height="auto";*/}

}
function slowon(id){/*这个实现菜单展开,初始条件必须是:菜单的高度="0px",不然会出错*/
var cld;
id=document.getElementById(id);
for(i=0;i<id.childNodes.length;i++){if(id.childNodes[i].nodeType==1){cld=id.childNodes[i];break;}}
var h = id.offsetHeight;
var h1=cld.offsetHeight;
id.style.height=parseInt(id.style.height)+sp+"px";
if (h1==0 || h<h1)setTimeout("slowon(\""+id.id+"\")",5);//通过比较内部子节点的高度与菜单的高度来判断是否已经打开完全
else{id.style.height="auto";}
}
/*=========================
在窗体载入完成后隐藏起一些菜单项
============================*/
function hidesth(){
var arr =[2,3,4,5,6,7];
for(i=0;i<arr.length;i++)
if (document.getElementById("menu"+ arr[i]+"_a")){document.getElementById("menu"+ arr[i]+"_a").onclick()//.display="none";document.getElementById("menu"+arr[i]+"_child").style.height="0px";
}
}

</script>
无限级算法thread-2780498-1-6.html 2780498-1-1.html

TOP

看我做的XP折叠菜单(不像您k我!)

@charset "utf-8";
/*css定义 */

body {
       background:#5c90d9;/*整个网页的背景颜色*/
}
/*.tit为每个菜单的标题样式  .list 为菜单项目的样式*/
.tit , .list{ width:183px; /*菜单的宽度*/
}

.tit {/*菜单标题的样式*/
       height: 22px;
       border: 1px solid #2a4dab;/*边框颜色*/
       border-bottom-style: none;/*底部边框没有*/
       background:#547DBE url(images/menu_head_bg.gif) repeat-x;/*背景样式依次为:颜色,图片路径,横向重复*/
       color: #D9E1F6;/*前景色*/
       font:bold 12px/22px "lucida Grande", verdana, lucida, Arial, helvetica, "宋体", sans-serif;/*文字样式依次为:粗体 大小/行高 字族*/
       text-indent: 35px;/*文字缩进*/
       margin-top:15px;/*外填充*/
       position: relative;       
}


.tit a ,.tit a:link , .tit a hover{/*菜单标题中的链接的样式,共同的部分*/
       color: #D9E1F6;
       display:block;
       text-decoration:none;
       width:183px;
       background-repeat: no-repeat;
       background-position: 166px 6px;       
}
.tit a:hover{
       color: #fff;/*鼠标经过时的颜色*/
}
/*====================
       菜单标题中的箭头图片
======================*/
.on{
       background-image: url(images/arrow_up.gif);/*向上的箭头-暗色*/
}
.on:hover{
       background-image: url(images/arrow_up_o.gif);/*向上的箭头-亮色*/
}
.off{
       background-image: url(images/arrow_down.gif);/*向下的箭头-暗色*/
}
.off:hover{
       background-image: url(images/arrow_down_o.gif);/*向下的箭头-亮色*/
}
/*====================
       菜单列表的样式
======================*/
.list{
       font-size: 12px;
       color: #002280;
       background: #fff no-repeat right bottom;
       width: 183px;/*宽度*/
       border: 1px solid #2A4DAB;
       text-align:left;
       padding:10px 10px;
       voice-family:"\"}\"";
       voice-family:inherit;
       width:163px;
       overflow:hidden;
}
html>body .list {
width:163px;
}
.list ul{
list-style-type:none;
margin:0;
padding:0;
padding-left:18px;
}
.list li{
margin:0;
padding:0;
padding-left:5px;
}
/*============
菜单链接的样式
==============*/
.list a{
color:#002280;
text-decoration:none;
}
.list a:link{
color:#002280;
}
.list a:hover{
color:#296DC1;
text-decoration:underline;
}
.list a:active{
color:#296DC1;
}
/*标题图标样式*/
.titpic {
       position: absolute;
       height: 32px;
       width: 32px;
       left: 0px;
       bottom: 0px;
}
/*每一个标题图标*/
#pc1{
       background: url(images/pepo.png) no-repeat;
}
#pc2{
       background: url(images/st.png) no-repeat;
}
#pc3{
       background: url(images/ring.png) no-repeat;
}
#pc4{
       background: url(images/pic.png) no-repeat;
}
#pc5{
       background: url(images/mv.png) no-repeat;
}
#pc6{
       background: url(images/up.png) no-repeat;
}
#pc7{
       background: url(images/help.png) no-repeat;
}
#menu1_child{
       background-image:url(images/bgmv.png);
}
/*#menu2_child{
       background-image:url(images/bgring.png);
}
*/#menu3_child{
       background-image:url(images/bgring.png);

}
#menu4_child{
       background-image:url(images/bgpic.png);

}
#menu5_child{
       background-image:url(images/bgmv.png);
}

说一下拆分过程:
先将xp截一个屏幕
然后ps里打开量了一下尺寸
把菜分成两部分:
第一部分:标题部分:
<div class="tit" id="menu2" title="菜单标题" >
<div class="titpic" id="pc2"></div>
<a href="#nojs" title="折叠菜单" target="_self" class="on" id="menu2_a" tabindex="2" onclick="onoff(this);return false" onkeypress="onoff(this)">系统设置</a>
</div>
最外面的div用来显示 外边框
里面的第一个div用来显示 那个小图片注意它的定位是绝对定位。而它的上一级div是相对定位,这样才能出来这个效果
a就不必说了

第二部分:菜单部分
<div class="list" id="menu2_child" title="菜单功能区">
  <ul>
    <li style="list-style-image:url(images/ico/1.gif) "><a href="#">环境变量</a></li>
    <li style="list-style-image:url(images/ico/2.gif) "><a href="#" onclick="return false">执行SQL</a></li>
    <li style="list-style-image:url(images/ico/3.gif) "><a href="#" onclick="return false">回收站</a></li>
    <li style="list-style-image:url(images/ico/4.gif) "><a href="#" onclick="return false">控制面板</a></li>
  </ul>
</div>
外面的div用来显示边框、底色、以及右下角的图标。
其他的不必说了,细细的看css文件就可以了。
无限级算法thread-2780498-1-6.html 2780498-1-1.html

TOP

看我做的XP折叠菜单(不像您k我!)

漂亮!

TOP

看我做的XP折叠菜单(不像您k我!)

很不错

再变化一下滑动速度就好了

比如100的滑动距离,可以分为3,2,1的速度递减滑动完成

那就更象了

TOP

看我做的XP折叠菜单(不像您k我!)

由于卷动菜单是靠判断 height所以并不是很逼真,现在正在改进。
无限级算法thread-2780498-1-6.html 2780498-1-1.html

TOP

看我做的XP折叠菜单(不像您k我!)

这里是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 处理结束
+-navbar.htm中的代码(在body里):
复制内容到剪贴板
代码:
<script language="JavaScript" type="text/JavaScript">
var show = true;
var hide = false;
//修改菜单的上下箭头符号
function my_on(head,body)
{
    var tag_a;
    for(var i=0;i<head.childNodes.length;i++)
    {
        if (head.childNodes[i].nodeName=="A")
        {
            tag_a=head.childNodes[i];
            break;
        }
    }
    tag_a.className="on";
}
function my_off(head,body)
{
    var tag_a;
    for(var i=0;i<head.childNodes.length;i++)
    {
        if (head.childNodes[i].nodeName=="A")
        {
            tag_a=head.childNodes[i];
            break;
        }
    }
    tag_a.className="off";
}
//添加菜单    
window.onload=function()
{
    m1 =new Menu("menu1",'menu1_child','dtu','100',show,my_on,my_off);
    m1.init();
    m2 =new Menu("menu2",'menu2_child','dtu','100',hide,my_on,my_off);
    m2.init();
    m3 =new Menu("menu3",'menu3_child','dtu','100',hide,my_on,my_off);
    m3.init();
    m4 =new Menu("menu4",'menu4_child','dtu','100',hide,my_on,my_off);
    m4.init();
    m5 =new Menu("menu5",'menu5_child','dtu','100',hide,my_on,my_off);
    m5.init();
    m6 =new Menu("menu6",'menu6_child','dtu','100',hide,my_on,my_off);
    m6.init();
    m7 =new Menu("menu7",'menu7_child','dtu','100',show,my_on,my_off);
    m7.init();
}
</script>
无限级算法thread-2780498-1-6.html 2780498-1-1.html

TOP

看我做的XP折叠菜单(不像您k我!)

初始化时第一个菜单的右符号方向不对吧

TOP

看我做的XP折叠菜单(不像您k我!)

漂亮,就是速度有点慢
高雅清香的春兰秋桂,不慕求虚荣,不阿谀权贵;芳香出于自然,不是为了博取别人欣赏。

TOP

看我做的XP折叠菜单(不像您k我!)

幻想曲在上个帖子中说
引用:
初始化时第一个菜单的右符号方向不对吧
嗯 ,那个还是稍微旧一点的
改一下就好了:
function hidesth(){
var arr =[2,3,4,5,6,7];
for(i=0;i<arr.length;i++)
if (document.getElementById("menu"+ arr[i]+"_a")){document.getElementById("menu"+ arr[i]+"_a").onclick;//模拟出点击事件
}
}
或者直接用2006-04-03日修改过的js
无限级算法thread-2780498-1-6.html 2780498-1-1.html

TOP

看我做的XP折叠菜单(不像您k我!)

代码中好象有一些错误啊,比如说47行里就提示报错'this.head' 为空或不是对象
不知道楼主你那里有没有这样的问题
hold the line

TOP

看我做的XP折叠菜单(不像您k我!)

这个菜单的确8错^_^刚好可以用来做我管理后台的导航栏了。

不过如果可以实现QQ菜单那样,只能弹开一个下拉列表就更好了,象微软的固然好,但是不够实用呀!

^_^打击一下楼主啦^_^

TOP

看我做的XP折叠菜单(不像您k我!)

鼠标移入移出显隐箭头显示不出来!?

TOP