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

    技术2022-05-11  52

                                     用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.οncοntextmenu=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 οnlοad="fnInit()" οnclick="fnDetermine()" bgcolor="#ccffcc"> <div status="false" οnmοuseοver="fnChirpOn()" οnmοuseοut="fnChirpOff()"

    id="oContextMenu" class="menu"></div>这里放你任意的其他的东西! ...<br>... 这里

    放你任意的其他的东西! ...<br>... 这里放你任意的其他的东西! ...<br><br>

    <P contextmenu="demo">这里是利用上下文菜单的里子!你把鼠标移动到这里,然后

    单击鼠标又键,可以看到菜单内容!<br>这里是利用上下文菜单的里子!你把鼠标移

    动到这里,然后单击鼠标又键,可以看到菜单内容!<br>这里是利用上下文菜单的里

    子!你把鼠标移动到这里,然后单击鼠标又键,可以看到菜单内容!<br>这里是利用

    上下文菜单的里子!你把鼠标移动到这里,然后单击鼠标又键,可以看到菜单内容!

    <br>这里是利用上下文菜单的里子!你把鼠标移动到这里,然后单击鼠标又键,可以

    看到菜单内容!<br></p><p>你也可以把鼠标放到下面的图象上面,点击又键!<p> <center><IMG SRC="http://lucky.myrice.com/javabk1.jpg"  contextmenu="demob"> </body> </html> 必须说明的是:你还可以自己定义菜单的无效[即变灰]的操作,也可以进一步定义更

    下一级的子菜单。这就只好留给你自己进行练习啦!:)


    最新回复(0)