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

[入库:2005年8月18日] [更新:2007年3月25日]

本文简介:选择自 ibreathe 的 blog

                                 用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"){

本文关键:XML、上下文、菜单
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top