Java开发网 Java开发网
注册 | 登录 | 帮助 | 搜索 | 排行榜 | 发帖统计  

您没有登录

» Java开发网 » 技术文章库  

按打印兼容模式打印这个话题 打印话题    把这个话题寄给朋友 寄给朋友    该主题的所有更新都将Email到你的邮箱 订阅主题
flat modethreaded modego to previous topicgo to next topicgo to back
作者 转载 用XML数据岛创建上下文菜单
jennyeh



发贴: 0
积分: 0
于 2003-07-23 17:39 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
上下文菜单就是用户在页面上单击右键时所显示的一组命令。微软的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="http://lucky.myrice.com/javabk1.jpg" 
contextmenu="demob">
</body>
</html>

必须说明的是:你还可以自己定义菜单的无效[即变灰]的操作,也可以进一步定义更下一级的子菜单。这就只好留给你自己进行练习啦!:)



作者 Re:转载 用XML数据岛创建上下文菜单 [Re:jennyeh]
mmbo



发贴: 0
积分: 0
于 2003-08-26 15:44 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
<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).selectSingleNode('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","111","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>
</head>
<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="http://lucky.myrice.com/javabk1.jpg" 
contextmenu="demob">
</body>
</html>



作者 Re:转载 用XML数据岛创建上下文菜单 [Re:jennyeh]
lemon2000



发贴: 0
积分: 0
于 2003-09-29 11:16 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
消化一下


作者 Re:转载 用XML数据岛创建上下文菜单 [Re:jennyeh]
hitaco





发贴: 432
积分: 31
于 2003-10-08 19:55 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
标题看不懂,什么叫数据岛?


作者 Re:转载 用XML数据岛创建上下文菜单 [Re:jennyeh]
showsscel





发贴: 22
积分: 0
于 2003-10-30 00:32 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
不错


作者 Re:转载 用XML数据岛创建上下文菜单 [Re:jennyeh]
wuchensir



发贴: 0
积分: 0
于 2003-11-21 13:37 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
顶一下,好东东


作者 Re:转载 用XML数据岛创建上下文菜单 [Re:jennyeh]
zerost



发贴: 0
积分: 0
于 2003-11-23 00:20 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list




flat modethreaded modego to previous topicgo to next topicgo to back
  已读帖子
  新的帖子
  被删除的帖子
Jump to the top of page

   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923