其实在网页上实现右键菜单的风格化已经是一个老话题了,正常情况下,网页上的右键菜单是默认IE右键选项,包括了一些常用的功能。
但有时候我们会遇到这样的问题,我们希望禁止访问者使用右键菜单或者希望屏蔽右键菜单的某些功能,比如,为了保护网页内容我们不希望访问者通过右键菜单来查看网页源代码,也不希望其通过右键来对网页内容进行选取、复制等,很多网页设计者在考虑这个问题的时候都是简单地对右键进行屏蔽,与其这样我们还不如用脚本来实现一个风格右键菜单,并在这个右键菜单中装上我们自己的内容。下面我们来尝试一下这个设想。
我们首先要考虑的问题是通过鼠标右键单击事件来调用一个函数,这个函数用来显示新的右键菜单的内容。我们知道鼠标的右键单击事件是通过document.oncontextmenu来调用的,如果我们自行定义document.οncοntextmenu=某个函数,这样就可以实现新右键菜单的调用了,关键问题是如何通过这个函数来控制菜单的显示,同时,还要通过窗体的单击事件document.body.onclick(一般指左键单击)来隐藏菜单,这样一个过程就完成了鼠标右键菜单的弹出和隐藏。
首先来看看这段脚本代码:
/*初始化*/
<script language="JavaScript1.2">
/*如果当前浏览器是Internet Explorer,document.all就返回真*/
if (document.all && window.print) {
/*选择菜单方块的显示样式*/
ie5menu.className = menuskin;
/*重定向鼠标右键事件的处理过程为自定义程序showmenuie5*/
document.oncontextmenu = showmenuie5;
/*重定向鼠标左键事件的处理过程为自定义程序hidemenuie5*/
document.body.onclick = hidemenuie5;
}
</script>
一般情况下页面装载完毕后才发生鼠标右键事件,所以为了不影响页面的装载速度我们可以把这段代码放在页面的最后面。这段代码很简单,首先检验是不是IE浏览器,如果是那么下面的定义就应该有效。也就是说当检查到客户端使用的浏览器是IE的时候那么当用户产生右键事件时就调用函数showmenuie5,当用户产生左键事件时就调用函数hidemenuie5。
解决了上面这个问题,现在我们要考虑如何通过函数showmenuie5和函数hidemenuie5来实现菜单的显示和隐藏。当然,这里的菜单并不是真正意义的右键菜单,而是我们自己做的一个div,在这个div中装上我们想要装的东西。通过鼠标事件调用函数来控制它的显隐,这就达到了使用鼠标右键一样的效果了。
下面我们来设计一个div,请看代码:
<div class="menuitems" url="javascript:history.back();">后退</div>
<div class="menuitems" url="javascript:history.forward();">前进</div>
<hr>
<div class="menuitems" url="http://www.webjx.com" target="_blank">网页教学</div>
<div class="menuitems" url="http://www.webjx.com/htmldata/sort/3.html" target="_blank">网页制作</div>
<div class="menuitems" url="http://www.webjx.com/htmldata/sort/4.html" target="_blank">动画制作</div>
<div class="menuitems" url="http://www.webjx.com/htmldata/sort/6.html" target="_blank">网络编程</div>
<hr>
<div class="menuitems" url="http://www.webjx.com/htmldata/sort/15.html" target="_blank">视频教程</div>
<div class="menuitems" url="http://www.webjx.com/htmldata/sort/1.html" target="_blank">业界新闻</div>
<hr>
<div class="menuitems" url="http://www.webjx.com/aboutus.htm" target="_blank">关于本站</div>
<div class="menuitems" url="mailto:tslxg@hotmail.com">与我联系</div>
</div>
这一块的最外层是一个id为ie5menu的div,我们定义了它的样式为skin0,当这个div处于显示状态时可能产生onMouseover事件和onMouseout事件以及onClick事件,就像我们在使用右键菜单时要对其中的选项进行操作一样,这里的onMouseover事件、onMouseout事件和onClick事件能够模拟整个鼠标右键事件。这里,我在右键菜单中定义了这么几个选项:页面操作功能、栏目导航功能、站点导航功能以及其它信息,能够起到良好的用户体验效果。
这里使用了div的url属性,其值可以是事件也可以是页面地址,当然,这个地址包括绝对地址和相对地址,上面的事件也很简单这里就不需要我多说了。
下面我们来分析几个函数:showmenuie5()函数(显示菜单)hidemenuie5()函数(隐藏菜单)以及jumptoie5()函数(右键菜单选项跳转)
showmenuie5()函数:
/*显示菜单*/
function showmenuie5() {
searchform.k.value=window.document.selection.createRange().text;
/*获取当前鼠标右键按下后的位置,据此定义菜单显示的位置*/
var rightedge = document.body.clientWidth-event.clientX;
var bottomedge = document.body.clientHeight-event.clientY;
/*如果从鼠标位置到窗口右边的空间小于菜单的宽度,就定位菜单的左坐标(Left)为当前鼠标位置向左一个菜单宽度*/
if (rightedge <ie5menu.offsetWidth)
ie5menu.style.left = document.body.scrollLeft + event.clientX - ie5menu.offsetWidth;
else
/*否则,就定位菜单的左坐标为当前鼠标位置*/
ie5menu.style.left = document.body.scrollLeft + event.clientX;
/*如果从鼠标位置到窗口下边的空间小于菜单的高度,就定位菜单的上坐标(Top)为当前鼠标位置向上一个菜单高度*/
if (bottomedge <ie5menu.offsetHeight)
ie5menu.style.top = document.body.scrollTop + event.clientY - ie5menu.offsetHeight;
else
/*否则,就定位菜单的上坐标为当前鼠标位置*/
ie5menu.style.top = document.body.scrollTop + event.clientY;
/*设置菜单可见*/
ie5menu.style.visibility = "visible";
return false;
}
hidemenuie5()函数:
/*隐藏菜单*/
function hidemenuie5() {
/*很简单,设置visibility为hidden就OK!*/
ie5menu.style.visibility = "hidden";
}
jumptoie5()函数:
function jumptoie5() {
var seltext=window.document.selection.createRange().text
if (event.srcElement.className == "menuitems") {
/*如果存在打开链接的目标窗口,就在那个窗口中打开链接*/
if (event.srcElement.getAttribute("target") != null)
window.open(event.srcElement.url, event.srcElement.getAttribute("target"));
else
/*否则,在当前窗口打开链接*/
window.location = event.srcElement.url;
}
}
既然本文讲的是用css+javascript实现右键菜单,前面讲到的都是javascript,好像还没有涉及到css,不用着急,下面就要用css来定义右键菜单的样式,否则这所谓的右键菜单就乱成一踏糊涂了。
首先看看ie5menu的样式skin0和skin1(根据不同的浏览器调用不同的皮肤),为了使“弹出”的右键菜单更具真实性,这里我们要模拟真实右键菜单的样式,请看下面的样式代码:
body {
font-family: "宋体";
font-size: 12px;
}
/*定义菜单方框的样式1*/
.skin0 {
position:absolute;
padding-top:4px;
text-align:left;
width:100px; /*宽度,可以根据实际的菜单项目名称的长度进行适当地调整*/
border:2px solid black;
background-color:menu; /*菜单的背景颜色方案,这里选择了系统默认的菜单颜色*/
font-family:"宋体";
line-height:20px;
cursor:default;
visibility:hidden; /*初始时,设置为不可见*/
}
/*定义菜单方框的样式2*/
.skin1 {
padding-top:4px;
cursor:default;
font:menutext;
position:absolute;
text-align:left;
font-family: "宋体";
font-size: 10pt;
width:100px; /*宽度,可以根据实际的菜单项目名称的长度进行适当地调整*/
background-color:menu; /*菜单的背景颜色方案,这里选择了系统默认的菜单颜色*/
border:1 solid buttonface;
visibility:hidden; /*初始时,设置为不可见*/
border:2 outset buttonhighlight;
}
/*定义菜单条的显示样式*/
.menuitems {
padding:2px 1px 2px 10px;
}
-->
上面的样式定义非常简单,但其属性值则是经过仔细调试而得到的,使其显示的结果尽量接近真实的右键菜单。
ok,所有的工作都做得差不多了,现在我们把上面讲的东西赶快组合起来看看实实在在的效果吧。
< head >
< meta http-equiv ="Content-Type" content ="text/html; charset=gb2312" >
< title > 超酷网页右键菜单 </ title >
< style >
body {
font-family : "宋体" ;
font-size : 12px ;
margin-left : 0px ;
margin-top : 10px ;
margin-right : 0px ;
margin-bottom : 0px ;
}
/* 定义菜单方框的样式1 */
.skin0 {
position : absolute ;
padding-top : 4px ;
text-align : left ;
width : 100px ; /* 宽度,可以根据实际的菜单项目名称的长度进行适当地调整 */
border : 2px solid black ;
background-color : menu ; /* 菜单的背景颜色方案,这里选择了系统默认的菜单颜色 */
font-family : "宋体" ;
line-height : 20px ;
cursor : default ;
visibility : hidden ; /* 初始时,设置为不可见 */
}
/* 定义菜单方框的样式2 */
.skin1 {
padding-top : 4px ;
cursor : default ;
font : menutext ;
position : absolute ;
text-align : left ;
font-family : "宋体" ;
font-size : 10pt ;
width : 100px ; /* 宽度,可以根据实际的菜单项目名称的长度进行适当地调整 */
background-color : menu ; /* 菜单的背景颜色方案,这里选择了系统默认的菜单颜色 */
border : 1 solid buttonface ;
visibility : hidden ; /* 初始时,设置为不可见 */
border : 2 outset buttonhighlight ;
}
/* 定义菜单条的显示样式 */
.menuitems {
padding : 2px 1px 2px 10px ;
}
-->
</ style >
< script language ="javascript" >
<!--
// 定义菜单显示的外观,可以从上面定义的2种格式中选择其一
var menuskin = " skin1 " ;
// 是否在浏览器窗口的状态行中显示菜单项目条对应的链接字符串
var display_url = 0 ;
function showmenuie5() {
// 获取当前鼠标右键按下后的位置,据此定义菜单显示的位置
var rightedge = document.body.clientWidth - event.clientX;
var bottomedge = document.body.clientHeight - event.clientY;
// 如果从鼠标位置到窗口右边的空间小于菜单的宽度,就定位菜单的左坐标(Left)为当前鼠标位置向左一个菜单宽度
if (rightedge < ie5menu.offsetWidth)
ie5menu.style.left = document.body.scrollLeft + event.clientX - ie5menu.offsetWidth;
else
// 否则,就定位菜单的左坐标为当前鼠标位置
ie5menu.style.left = document.body.scrollLeft + event.clientX;
// 如果从鼠标位置到窗口下边的空间小于菜单的高度,就定位菜单的上坐标(Top)为当前鼠标位置向上一个菜单高度
if (bottomedge < ie5menu.offsetHeight)
ie5menu.style.top = document.body.scrollTop + event.clientY - ie5menu.offsetHeight;
else
// 否则,就定位菜单的上坐标为当前鼠标位置
ie5menu.style.top = document.body.scrollTop + event.clientY;
// 设置菜单可见
ie5menu.style.visibility = " visible " ;
return false ;
}
function hidemenuie5() {
// 隐藏菜单
// 很简单,设置visibility为hidden就OK!
ie5menu.style.visibility = " hidden " ;
}
function highlightie5() {
// 高亮度鼠标经过的菜单条项目
// 如果鼠标经过的对象是menuitems,就重新设置背景色与前景色
// event.srcElement.className表示事件来自对象的名称,必须首先判断这个值,这很重要!
if (event.srcElement.className == " menuitems " ) {
event.srcElement.style.backgroundColor = " highlight " ;
event.srcElement.style.color = " white " ;
// 将链接信息显示到状态行
// event.srcElement.url表示事件来自对象表示的链接URL
if (display_url)
window.status = event.srcElement.url;
}
}
function lowlightie5() {
// 恢复菜单条项目的正常显示
if (event.srcElement.className == " menuitems " ) {
event.srcElement.style.backgroundColor = "" ;
event.srcElement.style.color = " black " ;
window.status = "" ;
}
}
// 右键下拉菜单功能跳转
function jumptoie5() {
// 转到新的链接位置
var seltext = window.document.selection.createRange().text
if (event.srcElement.className == " menuitems " ) {
// 如果存在打开链接的目标窗口,就在那个窗口中打开链接
if (event.srcElement.getAttribute( " target " ) != null )
window.open(event.srcElement.url, event.srcElement.getAttribute( " target " ));
else
// 否则,在当前窗口打开链接
window.location = event.srcElement.url;
}
}
// -->
</ script >
</ head >
< body >
< center >
< p > 点击右键看看效果- < a href ="http://www.webjx.com/" target ="_blank" > 网页教学网 </ a >
</ p >
</ center >
< div id ="ie5menu" class ="skin0" onMouseover ="highlightie5()" onMouseout ="lowlightie5()" onClick ="jumptoie5();" >
< div class ="menuitems" url ="javascript:history.back();" > 后退 </ div >
< div class ="menuitems" url ="javascript:history.forward();" > 前进 </ div >
< hr >
< div class ="menuitems" url ="http://www.webjx.com/" target ="_blank" > 网页教学 </ div >
< div class ="menuitems" url ="http://www.webjx.com/htmldata/sort/4.html" target ="_blank" > 动画制作 </ div >
< div class ="menuitems" url ="http://www.webjx.com/htmldata/sort/6.html" target ="_blank" > 网络编程 </ div >
< div class ="menuitems" url ="http://www.webjx.com/htmldata/sort/8.html" target ="_blank" > 网页素材 </ div >
< hr >
< div class ="menuitems" url ="http://www.webjx.com/htmldata/sort/15.html" target ="_blank" > 视频教程 </ div >
< div class ="menuitems" url ="http://www.webjx.com/htmldata/sort/5.html" target ="_blank" > 网页特效 </ div >
< hr >
< div class ="menuitems" url ="http://www.webjx.com/aboutus.htm" target ="_blank" > 关于本站 </ div >
< div class ="menuitems" url ="mailto:tslxg@hotmail.com" > 联系我们 </ div >
</ div >
</ body >
</ html >
< script language ="JavaScript1.2" >
// 如果当前浏览器是Internet Explorer,document.all就返回真
if (document.all && window.print) {
// 选择菜单方块的显示样式
ie5menu.className = menuskin;
// 重定向鼠标右键事件的处理过程为自定义程序showmenuie5
document.oncontextmenu = showmenuie5;
// 重定向鼠标左键事件的处理过程为自定义程序hidemenuie5
document.body.onclick = hidemenuie5;
}
</ script >