XP折叠菜单&仿QQ2006菜单

  特性:

  更好的外观:在菜单标题上添加了图标。

  更好的动作:实现了菜单的滑入,滑出效果。

  更易的使用:添加了许多注释,方便使用。

  当然还存在一些没有发现的问题。盼望大家指教:)

  实现折叠式动态改变style.height的值 这样不是很专业:) 不过很像了!

  100%的原装winXP折叠菜单的外观!如果不一样您提出来我改。

  (qq2006 在点击的时候还有一些抖动。)

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

screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmousewheel="return imgzoom(this);" onclick="if(!this.resized) {return true;} else {window.open('http://www.lxbzj.com/upload/200512/navbar2.png');}" border=0 alt="" align=center src="http://www.lxbzj.com/upload/200512/navbar2.png" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}">

screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onmousewheel="return imgzoom(this);" onclick="if(!this.resized) {return true;} else {window.open('http://www.lxbzj.com/upload/200604/qq2006.png');}" border=0 alt="" align=center src="http://www.lxbzj.com/upload/200604/qq2006.png" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}">

  测试网页的地址: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 处理结束