用XML数据岛创建上下文菜单

xml|菜单|创建|数据

 

上下文菜单就是用户在页面上单击右键时所显示的一组命令。微软的MSDN有一个简单的例子说明了怎样建立自定义菜单。这里,我们将通过XML的数据岛来快速创建自定义的上下文菜单。XML数据岛就是存在于HTML文档中的XML数据的一部分。通过XML文档对象模型[XML document object model (DOM)],我们可以轻松地参考和引用XML里的内容。我们这里利用XML数据岛来存储上下文菜单的多个定义,其中的每一个定义都可以和文档中的任一元素相联系。在没有定义的地方,将显示默认的菜单。
  Internet Explorer 5.0首次提出对上下文菜单和数据岛的支持,我们的例子在除Internet Explorer 5.0及以上的浏览器里将自动被忽略。因此,如果你使用的浏览器不是Internet Explorer 5.0及以上的版本,你将看不到任何效果,只能看到浏览器的默认菜单。如果你使用的是Internet Explorer 5.0及以上的浏览器,你可以在页面上点击鼠标右键来看效果。注意:点击图象和文字将显示不同的菜单。下面我们进行分析:
  
  第一步:定义菜单
  
  定义菜单是在文档XML数据岛里的进行的,你只需简单地在HTML文档的HEAD部分包含XML文件即可。例如:可以定义如下:
  
  <xml id="contextDef">
  <xmldata>
  <contextmenu id="demo">
  <item id="viewsource" value="查看源文件"/>
  <item id="back" value="返回上页"/>
  </contextmenu>
  <contextmenu id="demob">
  <item id="menu1" value="菜单项1" />
  <item id="menu2" value="菜单项2" />
  </contextmenu>
  </xmldata>
  </xml>
  
  在这里,带ID属性的<xml>根节点和<xmldata>节点是必须的[注意:在XML里大小写是敏感的]。一个contextmenu节点和它所包含的多个item节点定义了一个菜单。如果你要定义多个菜单,你只需定义多个contextmenu节点即可。contextmenu节点的id属性和页面中的相应元素相关联,item节点的id属性标明哪一个菜单项被我们选取。值得注意的是:在整个XML文档里,所有的ID属性不能重名。item节点的value值就是要在菜单里要显示的文字。
  
  第二步:和HTML里的元素相关联
  
  在上面的XML数据岛里,我们定义了两个菜单demo和demob,要想和HTML里的元素相关联,只需简单地把contextmenu的ID值和HTML元素的contextmenu属性相连接即可。
  <P contextmenu="demo">这个段落显示demo菜单的内容</P>
  <IMG SRC="usedemob.gif" contextmenu="demob">
  
  第三步:编写点击菜单项的执行的操作
  
  当我们单击菜单的每一个选项时,函数fnFireContext就被调用,并把代表所选菜单的一个对象参数传过来。为了处理单击的事件,只需编写简单的switch语句,根据不同的ID值执行不同的操作。例如:
  
  function fnFireContext(oItem) {
  switch (oItem.menuid) {
  case "viewsource":
  location.href = "view-source:" + location.href
  break;
  case "back":
  history.back()
  break;
  default:
  alert("您选的是:\n" + oItem.menuid + "\nText: " +
  oItem.innerText)
  }
  }
  
  你可以根据自己的需要进行更改鼠标单击事件的操作。
  
  第四步:定义菜单外观
  
  定义外观只需使用样式单即可,下面我们给出完整的例子,你完全可以拷贝、粘贴来看到本例子的效果!![注意:浏览器必需是IE5+]。
  
  <html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
  
  <style>
  .menu{ cursor: hand;
  display: none;
  position: absolute;
  top: 0; left: 0;
  overflow: hidden;
  background-color: "#CFCFCF";
  border: "1 solid";
  border-top-color: "#EFEFEF";
  border-left-color: "#EFEFEF";
  border-right-color: "#505050";
  border-bottom-color: "#505050";
  font: 10pt 宋体;
  margin:0pt;padding: 2pt
  }
  
  .menu SPAN {width: 100%; cursor: hand; padding-left: 10pt}
  .menu SPAN.selected {background: navy; color:white; cursor: hand}
  </style>
  
  <xml id="contextDef">
  <xmldata>
  <contextmenu id="demo">
  <item id="viewsource" value="查看源文件"/>
  <item id="back" value="后退……"/>
  <item id="meng" value="访问【孟宪会之精彩世界】"/>
  <item id="calculate" value="执行 JavaScript 代码"/>
  </contextmenu>
  <contextmenu id="demob">
  <item id="菜单项例子1" value="菜单项例子1" />
  <item id="菜单项例子2" value="菜单项例子2" />
  </contextmenu>
  </xmldata>
  </xml>
  
  <SCRIPT>
  
  // 定义全局变量
  var bContextKey=false;
  
  function fnGetContextID(el) {
  while (el!=null) {
  if (el.contextmenu) return el.contextmenu
  el = el.parentElement
  }
  return ""
  }
  
  function fnDetermine(){
  oWorkItem=event.srcElement;
  
  //键盘上的菜单键被按下时。
  if(bContextKey==true){
  
  //如果菜单的“状态”为“false”
  if(oContextMenu.getAttribute("status")=="false"){
  
  //捕获鼠标事件,以便和页面交互。
  oContextMenu.setCapture();
  
  //根据鼠标位置,确定菜单位置。
  oContextMenu.style.top=event.clientY + document.body.scrollTop +
  1;
  oContextMenu.style.left=event.clientX + document.body.scrollLeft +
  1;
  oContextMenu.innerHTML="";
  
  //设定菜单的“状态”为“true”
  var sContext = fnGetContextID(event.srcElement)
  if (sContext!="") {
  fnPopulate(sContext)
  oContextMenu.setAttribute("status","true");
  event.returnValue=false;
  }
  else
  event.returnValue=true
  }
  }
  else{
  
  // 如果键盘菜单键没有按下,并且菜单的“状态”为“true”。
  if(oContextMenu.getAttribute("status")=="true"){
  if((oWorkItem.parentElement.id=="oContextMenu") &&
  (oWorkItem.getAttribute("component")=="menuitem")){
  fnFireContext(oWorkItem)
  }
  
  // 当鼠标离开菜单或单击菜单项后,重设菜单(隐藏)
  
  oContextMenu.style.display="none";
  oContextMenu.setAttribute("status","false");
  oContextMenu.releaseCapture();
  oContextMenu.innerHTML="";
  event.returnValue=false;
  }
  }
  }
  
  
  function fnPopulate(sID) {
  var str=""
  var elMenuRoot =
  document.all.contextDef.XMLDocument.childNodes(0).selectSingle
  Node('contextmenu[@id="' + sID + '"]')
  if (elMenuRoot) {
  for(var i=0;i<elMenuRoot.childNodes.length;i++)
  str+='<span component="menuitem" menuid="' +
  elMenuRoot.childNodes[i].getAttribute("id") +
  '" id=oMenuItem' + i + '>' +
  elMenuRoot.childNodes[i].getAttribute("value") +
  "</SPAN><BR>"
  oContextMenu.innerHTML=str;
  oContextMenu.style.display="block";
  oContextMenu.style.pixelHeight = oContextMenu.scrollHeight
  }
  }
  
  function fnChirpOn(){
  if((event.clientX>0) &&(event.clientY>0)
  &&(event.clientX<document.body.offsetWidth)
  &&(event.clientY<document.body.offsetHeight)){
  oWorkItem=event.srcElement;
  if(oWorkItem.getAttribute("component")=="menuitem"){
  oWorkItem.className = "selected"
  }
  }
  }
  function fnChirpOff(){
  if((event.clientX>0) && (event.clientY>0) &&
  (event.clientX<document.body.offsetWidth) &&
  (event.clientY<document.body.offsetHeight)){
  oWorkItem=event.srcElement;
  if(oWorkItem.getAttribute("component")=="menuitem"){
  oWorkItem.className = ""
  }
  }
  }
  
  function fnInit(){
  if (oContextMenu) {
  oContextMenu.style.width=180;
  oContextMenu.style.height=document.body.offsetHeight/2;
  oContextMenu.style.zIndex=2;
  
  //设置菜单样式
  document.oncontextmenu=fnSuppress;
  }
  }
  
  function fnInContext(el) {
  while (el!=null) {
  if (el.id=="oContextMenu") return true
  el = el.offsetParent
  }
  return false
  }
  
  function fnSuppress(){
  if (!(fnInContext(event.srcElement))) {
  oContextMenu.style.display="none";
  oContextMenu.setAttribute("status","false");
  oContextMenu.releaseCapture();
  bContextKey=true;
  }
  
  fnDetermine();
  bContextKey=false;
  }
  
  function javameng(){
  window.open("http://lucky.myrice.com","_blank","width=400,height=
  400,top=20,left=20")
  }
  
  function fnFireContext(oItem) {
  
  // 自定义上下文菜单项的功能
  switch (oItem.menuid) {
  case "viewsource":
  location.href = "view-source:" + location.href
  break;
  case "back":
  history.back()
  break;
  case "meng":
  location.href="http://lucky.myrice.com"
  break;
  case "calculate":
  javameng()
  break;
  default:
  alert("你点击的菜单项是:\n\n\n" + oItem.menuid +"啊!!!")
  }
  }
  </SCRIPT>
  
  <BODY onload="fnInit()" onclick="fnDetermine()" bgcolor="#ccffcc">
  <div status="false" onmouseover="fnChirpOn()" onmouseout="fnChirpOff()" id="oContextMenu" class="menu"></div>这里放你任意的其他的东西! ...<br>... 这里放你任意的其他的东西! ...<br>... 这里放你任意的其他的东西! ...<br><br>
  <P contextmenu="demo">这里是利用上下文菜单的里子!你把鼠标移动到这里,然后单击鼠标又键,可以看到菜单内容!<br>这里是利用上下文菜单的里子!你把鼠标移动到这里,然后单击鼠标又键,可以看到菜单内容!<br>这里是利用上下文菜单的里子!
  你把鼠标移动到这里,然后单击鼠标又键,可以看到菜单内容!<br>这里是利用上下文菜单的里子!你把鼠标移动到这里,然后单击鼠标又键,可以看到菜单内容!<br>这里是利用上下文菜单的里子!你把鼠标移动到这里,然后单击鼠标又键,可以看到菜
  单内容!<br></p><p>你也可以把鼠标放到下面的图象上面,点击又键!<p>
  <center><IMG SRC="javabk1.jpg" 
  contextmenu="demob">
  </body>
  </html>
  
  必须说明的是:你还可以自己定义菜单的无效[即变灰]的操作,也可以进一步定义更下一级的子菜单。这就只好留给你自己进行练习啦!:)
  
  
  

时间: 2024-09-29 00:40:28

用XML数据岛创建上下文菜单的相关文章

Android编程实现为ListView创建上下文菜单(ContextMenu)的方法

本文实例讲述了Android编程实现为ListView创建上下文菜单(ContextMenu)的方法.分享给大家供大家参考,具体如下: ContextMenu称为上下文菜单,一般在控件上长按时弹出.今天我们学习ContextMenu的用法,这里与listview相结合,先在ListView显示几个Item,然后在Item上长按,弹出一个菜单(就是ContextMenu),点击菜单上的项目,提示刚才长按的Item的Position. main.xml文件 <?xml version="1.0

用XML数据岛结合Dom制作通讯录

一般情况下,如果要为网站提供一个通讯录程序,需要使用CGI结合后台数据库技术,这对WEB服务器的要求比较高,在很多不提供数据库功能的虚拟主机上甚至无法实现.当然,我们还可以采用TXT文本替代数据库,但TXT文本是比较难操作的,我们必须一行一行的读取判断,还要用分隔字符串实现字段分离,无法进行复杂运算. 现在,我们可以使用"可扩展的标记语言 (XML)" 来保存通讯录的数据,从而体现出XML的优点:表现数据的结构化方法,对于保存许多关系型数据结构的文件很有帮助. 一.基本原理: 在Mic

用XML数据岛结合Dom制作通讯录_XML/RSS

一般情况下,如果要为网站提供一个通讯录程序,需要使用CGI结合后台数据库技术,这对WEB服务器的要求比较高,在很多不提供数据库功能的虚拟主机上甚至无法实现.当然,我们还可以采用TXT文本替代数据库,但TXT文本是比较难操作的,我们必须一行一行的读取判断,还要用分隔字符串实现字段分离,无法进行复杂运算. 现在,我们可以使用"可扩展的标记语言 (XML)" 来保存通讯录的数据,从而体现出XML的优点:表现数据的结构化方法,对于保存许多关系型数据结构的文件很有帮助. 一.基本原理: 在Mic

旧代码回顾:YUI-ext 代码两侧/XML 数据岛/WSC 组件化

YUI-ext 代码两侧 旧时,写 yuiext 的代码的时候便学习过这些代码,两侧都是制作动画的代码.时间大概是两年前左右(07年初),但心路历程感觉是过了许久 呵呵,真的有天上十天,地下十年的感觉.那时候,靠自学,瞎浑的什么的都不懂,往这几句 script 撞呀撞呀,撞到做出效果为止!这不,一番经历,好歹也认识不少:JS 的道路并不坦,学 ajax 真的要下苦功! 言毕,丑汉终需见家翁,呵呵.下是那时稚嫩的代码. var fade_in_pic = function() { var pic

XML指南——XML数据岛

xml|数据 使用IE5.0或者更高的版本,XML数据可以以数据岛的形式嵌入HTML页面. 在HTML页面中嵌入XML数据 使用非官方标准的<xml>标记可以将XML数据嵌入到HTML页面中. XML数据可以象下面的例子那样嵌入HTML页面: <xml id="note">   <note>   <to>Tove</to>   <from>Jani</from>   <heading>Rem

用XML数据岛解决用户界面问题 - 1

xml|解决|数据|问题 从属列表问题(dependent list problem)"的问题时常被提出.问题时常出现于当你有两个以上的选择列表时,一个主列表有若干个选项,你希望当用户选择主列表中的某个选项时,在其他的从属列表中显示相关的选项.你可以通过eXtensible Markup Language(XML)的数据岛(data islands)来实现这一功能,把XML内嵌到你的HTML中.这一结果对在客户端的XML应用具有实践意义. 假设你为一家名为"CheapPc"的

用XML数据岛解决用户界面问题 - 2

xml|解决|数据|问题 把处理过程移到客户端 当Web服务器返回网页后,所有进一步的操作处理都在客户端进行.我原先认为如果向客户端发送一个大的数据集会使程序的速度放慢.但后来我却发现一次性发送所有数据比在客户与服务器之间来回地进行数据交换快得多.唯一可被注意到的停顿只是在IE5的XML解析器读取数据时的一个短暂的初始化停顿. HTML文件本身包含有4个元素:一个保存州名数据的选择列表(主列表),XML数据,一个从属列表的div标记占位符,和两个脚本.当州名选择列表的选项发生变化时,第二个脚本就

用XML数据岛解决用户界面问题

xml|解决|数据|问题     从属列表问题(dependent list problem)"的问题时常被提出.问题时常出现于当你有两个以上的选择列表时,一个主列表有若干个选项,你希望当用户选择主列表中的某个选项时,在其他的从属列表中显示相关的选项.你可以通过eXtensible Markup Language(XML)的数据岛(data islands)来实现这一功能,把XML内嵌到你的HTML中.这一结果对在客户端的XML应用具有实践意义. 假设你为一家名为"CheapPc&qu

HTML中的XML数据岛记录编辑与添加

xml|数据 <HTML>  <HEAD><Title>HTML中的数据岛中的记录集</Title></HEAD>  <body bkcolor=#EEEEEE text=blue bgcolor="#00FFFF">  <Table align=center width="100%"><TR><TD align="center">  &l