程序主菜单之javascript完全模拟

类别:网站制作 点击:0 评论:0 推荐:

<html>
<head>
</head>
<script language="javascript">
function PageLoad()
{
 /*var myMenu = new MainMenu('menu','test.xml');
 myMenu.Show();*/
 var myMenu = new MainMenu('menu');
 var menuFile = new MenuItem('File','文件',null,'F');
  var menuSave = new MenuItem('Save','保存','document.execCommand("SaveAs")','S');
  var menuExit = new MenuItem('Exit','退出','Exit()','X');
 var menuEdit = new MenuItem('Edit','编辑',null,'E');
 var menuView = new MenuItem('View','查看',null,'V');
  var menuProg = new MenuItem('Prog','通过程序脚本初始化','SelectOpt(this)');
  var menuConf = new MenuItem('Conf','通过配置文件初始化','SelectOpt(this)');
  var menuChk = new MenuItem('Chk','测试:复选项');
   var menuChk1 = new MenuItem('Chk1','测试:复选项1','CheckOpt(this)');
   var menuChk2 = new MenuItem('Chk1','测试:复选项2','CheckOpt(this)');
 var menuHelp = new MenuItem('Help','帮助',null,'H');
  var menuTopics = new MenuItem('Topics','帮助主题',null,'T');
  var menuContent = new MenuItem('Content','帮助内容',null,'C');
  var menuAbout = new MenuItem('About','关于 MenuItem','alert("MenuItem Ver1.00 by Akira([email protected])")','A');
 menuFile.addChild(menuSave);
 menuFile.addChild(menuExit);
 menuView.addChild(menuProg);
 menuView.addChild(menuConf);
 menuView.addLine(); //分隔行
 menuView.addChild(menuChk);
 menuChk.addChild(menuChk1);
 menuChk.addChild(menuChk2);
 menuHelp.addChild(menuTopics);
 menuHelp.addChild(menuContent);
 menuHelp.addLine();
 menuHelp.addChild(menuAbout);
 myMenu.addItem(menuFile);
 myMenu.addItem(menuEdit);
 myMenu.addItem(menuView);
 myMenu.addItem(menuHelp);
 myMenu.Show();
 menuEdit.Disable();
 menuTopics.Disable();
 menuContent.Disable();
 menuProg.Select();
 menuChk1.Check();
}
function contact()
{
 alert('联系我们');
}
function Exit()
{
 self.opener = self;
 self.close();
}
function SelectOpt(target)
{
 var editBox1 = document.getElementById('editBox1');
 var editBox2 = document.getElementById('editBox2');
 if (target.id == 'Conf')
 {
  editBox1.style.display = "none";
  editBox2.style.display = "block";
 }
 else
 {
  editBox2.style.display = "none";
  editBox1.style.display = "block";
 }
 target.Select();
}
function CheckOpt(target)
{
 target.Check();
}
</script>
<body style='padding:0 0 0 0;margin:0 0 0 0' onload='PageLoad()'>
<textarea id="editBox1" style="width:100%;height:90%">
通过程序初始化主菜单的例子:
<script>
 var myMenu = new MainMenu('menu');
 var menuFile = new MenuItem('File','文件',null,'F');
  var menuSave = new MenuItem('Save','保存','document.execCommand("SaveAs")','S');
  var menuExit = new MenuItem('Exit','退出','Exit()','X');
 var menuEdit = new MenuItem('Edit','编辑',null,'E');
 var menuView = new MenuItem('View','查看',null,'V');
  var menuProg = new MenuItem('Prog','通过程序脚本初始化','SelectOpt(this)');
  var menuConf = new MenuItem('Conf','通过配置文件初始化','SelectOpt(this)');
  var menuChk1 = new MenuItem('Chk1','测试:复选项1','CheckOpt(this)');
  var menuChk2 = new MenuItem('Chk1','测试:复选项2','CheckOpt(this)');
 var menuHelp = new MenuItem('Help','帮助',null,'H');
  var menuTopics = new MenuItem('Topics','帮助主题',null,'T');
  var menuContent = new MenuItem('Content','帮助内容',null,'C');
  var menuAbout = new MenuItem
   ('About','关于 MenuItem','alert('MenuItem Ver1.00 by Akira([email protected])')','A');
 myMenu.addItem(menuFile);
 myMenu.addItem(menuEdit);
 myMenu.addItem(menuView);
 myMenu.addItem(menuHelp);
 menuFile.addChild(menuSave);
 menuFile.addChild(menuExit);
 menuView.addChild(menuProg);
 menuView.addChild(menuConf);
 menuView.addLine(); //分隔行
 menuView.addChild(menuChk1);
 menuView.addChild(menuChk2);
 menuHelp.addChild(menuTopics);
 menuHelp.addChild(menuContent);
 menuHelp.addLine();
 menuHelp.addChild(menuAboug);
 myMenu.Show();
 menuEdit.Disable();
 menuTopics.Disable();
 menuContent.Disable();
 menuProg.Select();
 menuChk1.Check();
</script>
</textarea>
<textarea id="editBox2" style="width:100%;height:90%;display:none">
通过配置文件初始化主菜单的例子:
<!--xml配置文件,例如保存为test.xml-->
<?xml version="1.0" encoding="gb2312" standalone="yes"?>
<MainMenu>
 <MenuItem id="File" Text="文件" Accelerator="F">
  <MenuItem id="Save" Text="保存" Accelerator="S" onClick="document.execCommand('SaveAs')"/>
  <MenuItem id="Exit" Text="退出" Accelerator="X" onClick="Exit()"/>
 </MenuItem>
 <MenuItem id="Edit" Text="编辑" Accelerator="E" Disabled="true">
 </MenuItem>
 <MenuItem id="View" Text="查看" Accelerator="V">
  <MenuItem id="Prog" Text="通过程序脚本初始化" Selected="true" onClick="SelectOpt(this)"/>
  <MenuItem id="Conf" Text="通过配置文件初始化" onClick="SelectOpt(this)"/>
  <MenuItem/>
  <MenuItem id="Chk1" Text="测试:复选项1" Checked="true" onClick="CheckOpt(this)"/>
  <MenuItem id="Chk2" Text="测试:复选项2" onClick="CheckOpt(this)"/>
 </MenuItem>
 <MenuItem id="Help" Text="帮助" Accelerator="H">
  <MenuItem id="Topics" Text="帮助主题" Accelerator="T" Disabled="true"/>
  <MenuItem id="Content" Text="帮助内容" Accelerator="C" Disabled="true"/>
  <MenuItem/>
  <MenuItem id="About" Text="关于 MenuItem" Accelerator="A" onClick="alert('MenuItem Ver1.00 by Akira([email protected])')"/>
 </MenuItem>
</MainMenu>
<script>
 var myMenu = new MainMenu('menu','test.xml');  //从配置文件test.xml中读取菜单信息
 myMenu.Show();
</script>
</textarea>
</body>
</html>


<!-------------------------------------------------------------------------
      菜单控件主体程序部分
    Version 1.00 Akira ([email protected])
-------------------------------------------------------------------------->
<script language="javascript">

function MenuItem(id, text, clickEvent, accelerator, subWidth)
{
 this.id = null;
 this.text = null;
 this.accelerator = null;
 this.clickEvent = clickEvent;
 
 if (id == null)
 {
  this.id = "menu" + (new Date()).getTime();
 }
 else
  this.id = id;
 this.text = text;
 if (subWidth == null)
 {
  this.subWidth = 0;
  for (var i = 0; this.text != null && i < this.text.length; i++)
  {
   this.subWidth = this.subWidth - 0 + (text.charCodeAt(i) > 127 ? 20 : 10);
  }
  //this.subWidth = this.text != null ? this.text.length * 16 : 96;//100;
 }
 else
  this.subWidth = subWidth;

 if (clickEvent == null)
  this.onclick = function(){};
 else
  this.onclick = function(){eval(clickEvent);};

 if (accelerator != null)   //快捷键
 {
  this.accelerator = accelerator;
 }

 this.subMenuItems = new Array();

 this.visible = true;
 this.disabled = false;
 this.checked = false;
 this.selected = false;

 MenuItem.prototype.Hide = function()
 {
  this.visible = false;
  this._span.style.display = "none";
 }
 MenuItem.prototype.Show = function()
 {
  this.visible = true;
  this._span.style.display = "block";
 }
 MenuItem.prototype.Enable = function()
 {
  this.disabled = false;
  this._span.EventHandler = this;
  this._span.onmouseover = function(){this.EventHandler._span_MouseOver(this,event);}
  this._span.onmouseout = function(){this.EventHandler._span_MouseOut(this,event);}
  this._span.onclick = function(){this.EventHandler._span_Click(this,event);}
  this._span.style.color = "#000000";
 }
 MenuItem.prototype.Disable = function()
 {
  this.disabled = true;
  this._span.onmouseover = function(){}
  this._span.onmouseout = function(){}
  this._span.onclick = function(){}
  this._span.style.color = "#ACA899";
 }
 MenuItem.prototype.Check = function()
 {
  if (!this.checked)
  {
   var textObj = document.createElement('b');
   textObj.innerText = '√';
   this._span.appendChild(textObj);
   for (var i = 0; i < this._span.childNodes.length - 1; i++)
   {
    this._span.appendChild(this._span.removeChild(this._span.childNodes[i]));
   }
   this.checked = true;
   this._span.style.paddingLeft = "6px";
  }
  else
  {
   this._span.removeChild(this._span.childNodes[0]);
   this.checked = false;
   this._span.style.paddingLeft = "18px";
  }
 }
 MenuItem.prototype.Select = function()
 {
  var parent = this.parent;
  for (var i = 0; i < parent.subMenuItems.length; i++)
  {
   parent.subMenuItems[i]._unselect();
  }
  var liObj = document.createElement("li");
  this._span.appendChild(liObj);
  for (var i = 0; i < this._span.childNodes.length - 1; i++)
  {
   liObj.appendChild(this._span.removeChild(this._span.childNodes[i]));
  }
  this.selected = true;
  //this.subWidth = this.subWidth - 0 + 16;
  this._span.style.paddingLeft = "2px";
 }
 MenuItem.prototype._unselect = function()
 {
  if (this.selected)
  {
   var liObj = this._span.removeChild(this._span.childNodes[0]);
   for (var i = 0; i < liObj.childNodes.length; i++)
   {
    this._span.appendChild(liObj.childNodes[i]);
   }
   this.selected = false;
   this._span.style.paddingLeft = "18px";
   //this.subWidth = this.subWidth - 16;
  }
 }

 MenuItem.prototype.addChild = function(menuItem)
 {
  this.subMenuItems.push(menuItem);
  menuItem.parent = this;
 }
 MenuItem.prototype.addLine = function()
 {
  this.addChild(new MenuItem());
 }
 MenuItem.prototype.hasChild = function()
 {
  return this.subMenuItems.length > 0;
 }

 this._span = document.createElement("span");
 this._span.id = this.id;
 this._span.style.cursor = "default";
 if (this.text == null)
 {
  this._span.appendChild(document.createElement("hr"));
  this._span.style.height = "2px";
  this._span.style.marginTop = "2px";
  this._span.style.marginBottom = "2px";
 }
 else
 {
  if (accelerator != null)
  {
   var site = text.indexOf(accelerator);

   if (site != -1)
   {
    var part1 = text.slice(0, site);
    var part2 = text.slice(site + 1);
    
    var textNode1 = document.createTextNode(part1);
    var textNode2 = document.createTextNode(part2);
    var node = document.createElement("font");
    node.style.textDecoration = "underline";
    node.innerText = accelerator;
    this._span.appendChild(textNode1);
    this._span.appendChild(node);
    this._span.appendChild(textNode2);
   }
   else
   {
    var textNode = document.createTextNode(text + "(");
    var node = document.createElement("font");
    node.style.textDecoration = "underline";
    node.innerText = accelerator;
    this._span.appendChild(textNode);
    this._span.appendChild(node);
    this._span.appendChild(document.createTextNode(")"));
    this.subWidth = this.subWidth - 0  + 48;
   }
  }
  else
  {
   var textNode = document.createTextNode(text);
   this._span.appendChild(textNode);
  }
  this._span.style.height = "20px";
  this._span.style.marginTop = "2px";
  this._span.style.marginBottom = "2px";
  this._span.style.fontSize = "12px";
  this._span.style.paddingTop = "5px";
  this._span.style.paddingLeft = "18px";
  this._span.style.paddingRight = "10px";

  this._span.EventHandler = this;
  this._span.onmouseover = function(){this.EventHandler._span_MouseOver(this,event);}
  this._span.onmouseout = function(){this.EventHandler._span_MouseOut(this,event);}
  this._span.onclick = function(){this.EventHandler._span_Click(this,event);}
 }
 
 if (accelerator != null)
 {
  this.accelerator = accelerator.charCodeAt(0);

 }

 MenuItem.prototype.ShowSubmenu = function()
 {
  var pos = this.getObjPosition();
  var subSpan = document.createElement("span");
  subSpan.style.position = "absolute";
  if(this.parent instanceof MainMenu)
  {
   subSpan.style.left = pos[0];
   subSpan.style.top = pos[1] + this._span.clientHeight;
  }
  else
  {
   subSpan.style.left = pos[0] + this._span.clientWidth + 1;
   subSpan.style.top = pos[1];
  }
  subSpan.style.paddingLeft = "0px";
  subSpan.style.width = 0;

  subSpan.style.backgroundColor = "#FFFFFF";
  subSpan.style.border = "solid 1px #ACA899";
  subSpan.style.color = "#000000";
  subSpan.className = "subMenu";
  subSpan.owner = this.id;
  //this._span.onmouseout = function(){};

  for (var i = 0; i < this.subMenuItems.length; i++)
  {
   this.subMenuItems[i]._span.style.marginTop = 0;
   this.subMenuItems[i]._span.style.marginBottom = 0;
   this.subMenuItems[i]._span.style.width = "100%";
   if (this.subWidth < this.subMenuItems[i].subWidth)
   {
    this.subWidth = this.subMenuItems[i].subWidth;
   }
   subSpan.appendChild(this.subMenuItems[i]._span);
  }
  
  subSpan.style.width = this.subWidth > 96 ? this.subWidth : 96;
  //this._span.appendChild(subSpan);
  document.body.appendChild(subSpan);
  document.body.focus();
 }
 MenuItem.prototype._span_Click = function(sender, event)
 {
  if (!this.hasChild() || this.clickEvent)
  {
   this.hideSubmenu(true);
   this.onclick();
  }
  else
  {
   if(this.hasChild())
   {
    this.ShowSubmenu();
    this.parent._showSub = true;
   }
  }
  if (event.stopPropagation)
   event.stopProgpagation();
  else
   event.cancelBubble = true;
 }

 MenuItem.prototype._span_MouseOver = function(sender, event)
 {
  this.hideSubmenu();
  this._activeMenu(sender);
  if(this.hasChild() && (this.parent._showSub || this.parent instanceof MenuItem))
  {
   this.ShowSubmenu();
  }
 }
 MenuItem.prototype._span_MouseOut = function(sender, event)
 {
  this._cleanMenu(sender);
  //this.hideSubmenu();
 }
 MenuItem.prototype._activeMenu = function(menuSpan)
 {
  menuSpan.style.backgroundColor = "#316AC5";
  menuSpan.style.color = "#FFFFFF";
 }
 MenuItem.prototype._cleanMenu = function(menuSpan)
 {
  if (menuSpan.parentNode.className == "subMenu")
   menuSpan.style.backgroundColor = "#FFFFFF";
  else
   menuSpan.style.backgroundColor = "#F1EEE5";
  menuSpan.style.color = "#000000"; 
 }
 MenuItem.prototype.hideSubmenu = function(bHideAll)
 {
  var subMenus = document.getElementsByTagName("span");
  for (var i = subMenus.length - 1; i >= 0; i--)
  {
   if (subMenus[i].className == "subMenu" &&
    (bHideAll || !this.isParentOf(subMenus[i].owner)))
   {
    if (bHideAll)
    {
     var parent = this.parent;
     while (parent != null)
     {
      parent._showSub = false;
      parent = parent.parent;
     }
    }
    this._cleanMenu(this._span);
    subMenus[i].parentNode.removeChild(subMenus[i]);
   }
  }
 }
 MenuItem.prototype.isParentOf = function(owner)
 {
  var parent = this.parent;
  while(parent != null)
  {
   if (owner == parent.id)
    return true;
   parent = parent.parent;
  }
  return false;
 }
 //获取对象坐标
 MenuItem.prototype.getObjPosition = function() {
  var obj = this._span;
  var objLeft = obj.offsetLeft;
  var objTop = obj.offsetTop;
  var objParent = obj.offsetParent;
  while (objParent.tagName != "BODY") {
   objLeft += objParent.offsetLeft;
   objTop += objParent.offsetTop;
   objParent = objParent.offsetParent;
  }
  return([objLeft,objTop]);
 }

 MenuItem.Instances[this.id] = this;
 MenuItem.Instances.All.push(this);

 if (document.body.onkeydown == null)
 {
  document.body.onkeydown = function()
  {
   for (var i = 0; i < MenuItem.Instances.All.length; i++)
   {
    if (MenuItem.Instances.All[i].accelerator != null)
    {
     if (event.altKey && event.keyCode == MenuItem.Instances.All[i].accelerator)
     {
       MenuItem.Instances.All[i]._span_Click.call(MenuItem.Instances.All[i],MenuItem.Instances.All[i]._span,event);
     }
    }
   }
  }
 }
 if (document.body.onclick == null)
 {
  document.body.onclick = function()
  {
   MenuItem.Instances.All[0].hideSubmenu(true);
  }
 }
}

MenuItem.Instances = new Array();
MenuItem.Instances.All = new Array();

function MainMenu(id,cfgSrc)
{
 this.items = new Array();
 this.parent = null;
 this.id = id;

 MainMenu.prototype._loadCfg = function(src)   //从配置文件中读取
 {
  try
  {
   var objXMLDoc = new ActiveXObject("Microsoft.XMLDOM");
   objXMLDoc.async = false;
   objXMLDoc.load(src);
   if (objXMLDoc.documentElement == null)
    throw new TypeError("XML文档解析失败!");
   return objXMLDoc;
  }
  catch(e)
  {
   alert("XML文档解析失败!");
   throw new TypeError("XML文档解析失败!");
  }
 }
 MainMenu.prototype._applyCfg = function(element, menuItem)
 {
  var id = element.getAttribute("id");
  var text = element.getAttribute("Text");
  var onClick = element.getAttribute("onClick");
  var Accelerator = element.getAttribute("Accelerator");
  
  var subMenuItem = new MenuItem(id,text,onClick,Accelerator);
  if(menuItem != null)
   menuItem.addChild(subMenuItem);
  else
   this.addItem(subMenuItem);

  for (var i = 0; i < element.childNodes.length; i++)
  {
   if (element.childNodes[i].tagName == "MenuItem")
   {
    this._applyCfg(element.childNodes[i], subMenuItem);
   }
  }
 }
 
 MainMenu.prototype._setStatus = function(xmlDoc)
 {
  var cfgElements = xmlDoc.getElementsByTagName("MenuItem");

  for (var i = 0; i < cfgElements.length; i++)
  {
   var element = cfgElements[i];
  
   var id = element.getAttribute("id");
   var checked =  element.getAttribute("Checked");
   var selected = element.getAttribute("Selected");
   var visible = element.getAttribute("Visible");
   var disabled = element.getAttribute("Disabled");

   if (id == null)
   {
    continue;
   }
   if (checked == "true")
   {
    MenuItem.Instances[id].Check();
   }
   if (selected == "true")
   {
    MenuItem.Instances[id].Select();
   }
   if (visible == "false")
   {
    MenuItem.Instances[id].Hide();
   }
   if (disabled == "true")
   {
    MenuItem.Instances[id].Disable();
   }
  }
 }

 MainMenu.prototype.menuItem = function(id)
 {
  return this._find(id, this.items);
 }
 MainMenu.prototype._find = function(id, items)
 {
  for (var i = 0; i < items.length; i++)
  {
   if (items[i].id == id)
   {
    return items[i];
   }
   if (items[i].subMenuItems.length > 0)
   {
    this._find(id, items[i].subMenuItems);
   }
  }
  return null;
 }

 MainMenu.prototype.addItem = function(menuItem)
 {
  this.items.push(menuItem);
  menuItem.parent = this;
 }
 MainMenu.prototype.removeItem = function(id)
 {
  return this._delete(id, this.items);
 }

 MainMenu.prototype._delete = function(id, items)
 {
  for (var i = 0; i < items.length; i++)
  {
   if (items[i].id == id)
   {
    var item = items[i];
    items.splice(i);
    return item;
   }
   if (items[i].subMenuItems.length > 0)
   {
    this.find(id, items[i].subMenuItems);
   }
  }
  return null;
 }
 
 this._div = document.createElement("div");
 this._div.id = this.id;
 this._div.style.height = "24px";
 this._div.style.backgroundColor = "#F1EEE5";
 //document.body.appendChild(this._div);
 
 if(cfgSrc != null)
 {
  var objXMLDoc = this._loadCfg(cfgSrc);
  var rootElement = objXMLDoc.documentElement;

  if(rootElement.tagName != "MainMenu")
  {
   alert("XML文档不是合法的主菜单配置文件!(根元素的标签名不是MainMenu)");
   throw new TypeError("XML文档不是合法的主菜单配置文件!(根元素的标签名不是MainMenu)");
  }

  for (var i = 0; i < rootElement.childNodes.length; i++)
  {
   if (rootElement.childNodes[i].tagName == "MenuItem")
   {
    this._applyCfg(rootElement.childNodes[i]);
   }
  }

  this._setStatus(objXMLDoc);
 }

 MainMenu.prototype.Show = function()
 {
  document.body.appendChild(this._div);
  for (var i = 0; i < document.body.childNodes.length; i++)
  {
   if(document.body.childNodes[i].id != this.id)
   {
    document.body.appendChild(document.body.removeChild(document.body.childNodes[i]));
   }
  }
  for (var i = 0; i < this.items.length; i++)
  {
   this._div.appendChild(this.items[i]._span);
  }
 }
}

</script>

本文地址:http://com.8s8s.com/it/it30628.htm