您的位置:首页 > Web前端 > JavaScript

Javascript公共脚本库系列(三): 格式化事件对象/事件对象详解

2009-09-11 14:34 896 查看

本文转自:/article/4677242.html

一.摘要

本系列文章是为了抽象通用的,跨浏览器的脚本方法.

本篇文章为脚本库添加跨浏览器的获取事件对象的方法,重点是讲解javascript中的事件对象的原理.希望通过分享微薄的知识告诉大家如何进行"加法运算"而不是死记硬背"1+1=2".

二.实现效果

本次添加的两个函数用于获取事件对象,事件对象中包含很多的信息,比如鼠标的坐标,从而实现自己想要的功能.

实例一可以在屏幕上捕获鼠标按键代码和键盘按键代码:







实例二实现重写鼠标右键菜单:





三.事件对象简介

事件源和事件对象就相当于C#中事件函数的sender和EventArgs参数.

事件源是产生事件的元素本身,而事件对象则带有事件相关的信息.事件对象只有在发生事件时才被创建,并且只能在事件中访问.当事件关联的处理函数执行完毕后,事件对象就被销毁.

事件对象带有很多有用的信息,比如屏幕坐标,按键代码,是否冒泡等.但是可惜的是FireFox支持的DOM事件模型和IE的事件模型并不完全一致,获取事件对象的方式也不相同.在IE中通过window.event使用当前的事件对象,而DOM则规定事件对象要作为唯一参数传递给事件处理函数.

四.实现代码

我们的ScriptHelper类又要添加两个新方法了:

/*获取事件对象
使用举例:<divonclick="varoEvent=ScriptHelper.getEvent();"></div>
注意事项:只能在事件中使用.比如onclick中.不能在自定义方法中使用.
*/
scriptHelper.prototype.getEvent=function()
{
if(window.event)
{
returnwindow.event;
}
else
{
returnthis.getEvent.caller.arguments[0];
}
}

/*取消冒泡事件
使用举例:<divonclick="varoEvent=ScriptHelper.cancelBubble();"></div>
注意事项:只能在事件中使用.比如onclick中.不能在自定义方法中使用.
*/
scriptHelper.prototype.cancelBubble=function()
{
if(window.event)
{
window.event.cancelBubble=true;
}
else
{
returnthis.cancelBubble.caller.arguments[0].cancelBubble=true;
}
}


.csharpcode{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
MARGIN:0em
}
.csharpcode.rem{
COLOR:#008000
}
.csharpcode.kwrd{
COLOR:#0000ff
}
.csharpcode.str{
COLOR:#006080
}
.csharpcode.op{
COLOR:#0000c0
}
.csharpcode.preproc{
COLOR:#cc6633
}
.csharpcode.asp{
BACKGROUND-COLOR:#ffff00
}
.csharpcode.html{
COLOR:#800000
}
.csharpcode.attr{
COLOR:#ff0000
}
.csharpcode.alt{
MARGIN:0em;WIDTH:100%;BACKGROUND-COLOR:#f4f4f4
}
.csharpcode.lnum{
COLOR:#606060
}

这两个方法十分简单.getEvent用于获取事件对象.cancelBubble和getEvent类似,但不是返回事件对象,而是取消事件对象的冒泡事件.

也许有人会觉得getEvent和cancelBubble中有重复代码,认为可以在cancelBubble中调用getEvent获取事件对象,然后再取消冒泡事件.然而不能这么做,这两个事件都只能用在事件处理函数中,cancelBubble已经是一个自定义方法,不能在自定义方法中使用getEvent.原因是在DOM事件中,事件对象是事件的唯一参数.对于FireFox我们是通过caller.arguments[0]来捕获事件对象,caller表示此方法的调用者,必须为事件.下文中还有对于事件参数的讲解.

五.应用实例

实例一在屏幕上捕获鼠标按键代码和键盘按键代码

实例代码:

<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ScriptHelper类测试--事件对象实例--获取键盘鼠标按键代码</title>
<scriptsrc="http://files.cnblogs.com/zhangziqiu/ScriptHelper.js"type="text/javascript"></script>
<styletype="text/css">
.cursorHand{cursor:pointer;}
</style>
</head>
<body>
<scripttype="text/javascript">
functiongetKeyCode()
{
varoEvent=ScriptHelper.getEvent();
alert("KeyCode:"+oEvent.keyCode);
}

functiongetMouseButtonCode()
{
varoEvent=ScriptHelper.getEvent();
alert("MouseButtonCode:"+oEvent.button);
}

ScriptHelper.addEventListener(document,"keydown",getKeyCode);
ScriptHelper.addEventListener(document,"mousedown",getMouseButtonCode);
</script>

</body>
</html>

.csharpcode{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
MARGIN:0em
}
.csharpcode.rem{
COLOR:#008000
}
.csharpcode.kwrd{
COLOR:#0000ff
}
.csharpcode.str{
COLOR:#006080
}
.csharpcode.op{
COLOR:#0000c0
}
.csharpcode.preproc{
COLOR:#cc6633
}
.csharpcode.asp{
BACKGROUND-COLOR:#ffff00
}
.csharpcode.html{
COLOR:#800000
}
.csharpcode.attr{
COLOR:#ff0000
}
.csharpcode.alt{
MARGIN:0em;WIDTH:100%;BACKGROUND-COLOR:#f4f4f4
}
.csharpcode.lnum{
COLOR:#606060
}

实例说明:

本实例中使用了ScriptHelper.getEvent方法获取事件对象,并且获取了事件对象中的键盘代码和鼠标按键代码.注意实例中是使用ScriptHelper.addEventListener将getKeyCode和getMouseButtonCode添加到事件上.此时getKeyCode函数等同于onkeydown事件,所以在getKeyCode函数中调用ScriptHelper.getEvent就等同于在onkeydown事件中调用.

但是注意不能这么写:

<bodyonkeydown="getKeyCode();">


.csharpcode{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
MARGIN:0em
}
.csharpcode.rem{
COLOR:#008000
}
.csharpcode.kwrd{
COLOR:#0000ff
}
.csharpcode.str{
COLOR:#006080
}
.csharpcode.op{
COLOR:#0000c0
}
.csharpcode.preproc{
COLOR:#cc6633
}
.csharpcode.asp{
BACKGROUND-COLOR:#ffff00
}
.csharpcode.html{
COLOR:#800000
}
.csharpcode.attr{
COLOR:#ff0000
}
.csharpcode.alt{
MARGIN:0em;WIDTH:100%;BACKGROUND-COLOR:#f4f4f4
}
.csharpcode.lnum{
COLOR:#606060
}

因为上面的代码等同于:

body.onkeydown=function()
{
getKeyCode();
}

实例二重写鼠标右键菜单

实例代码:

<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ScriptHelper类测试--事件对象实例--重写鼠标右键菜单</title>
<scriptsrc="http://files.cnblogs.com/zhangziqiu/ScriptHelper.js"type="text/javascript"></script>
<styletype="text/css">
.cursorHand{cursor:pointer;}
.menu
{
background:#FFFFFFnonerepeatscroll00;
border:1pxsolid#ACA899;
color:#000000;
font-size:12px;
position:absolute;
display:none;
}
.menuul
{
list-style-image:none;
list-style-position:outside;
list-style-type:none;
margin:3px;
padding:3px;
}
.menuulli
{
cursor:pointer;
margin-bottom:5px;
}
</style>
</head>
<bodystyle="position:relative;">
<scripttype="text/javascript">
</script>

<div>测试文字:欢迎访问http://zhangziqiu.cnblogs.com一起学习,一起进步.</div>

<divid="mouseRightButtonMenu"class="menu"onclick="ScriptHelper.cancelBubble();">
<ul>
<liid="divMouseMenu1">查看选中内容</li>
<li><ahref="http://zhangziqiu.cnblogs.com"target="_blank">返回博客首页</a></li>
</ul>
</div>
<scripttype="text/javascript">
//显示鼠标右键菜单
functionshowMouseRightButtonMenu()
{
ScriptHelper.cancelBubble();
varoEvent=ScriptHelper.getEvent();
varmenu=document.getElementById('mouseRightButtonMenu');
if(oEvent.button==2)
{
menu.style.display="block";
menu.style.left=oEvent.clientX+"px";
menu.style.top=oEvent.clientY+"px";
}
}

//关闭鼠标右键菜单
functioncloseMouseRightButtonMenu()
{
varoEvent=ScriptHelper.getEvent();
if(oEvent.button==0||oEvent.button==1)
{
ScriptHelper.closeDivCommon('mouseRightButtonMenu');
}
}

//空函数,用于取消FireFox默认的鼠标右键菜单
functionblankMethod()
{
returnfalse;
}

//添加鼠标右键菜单的相关事件
document.onclick=blankMethod;
document.ondblclick=blankMethod;
ScriptHelper.addEventListener(document,"mousedown",showMouseRightButtonMenu);
ScriptHelper.addEventListener(document,"click",closeMouseRightButtonMenu);
ScriptHelper.addEventListener(document,"contextmenu",blankMethod);

/*菜单项相关函数*/
functionmouseMenu1()
{
ScriptHelper.closeDivCommon("mouseRightButtonMenu");

varselectText="未选中任何内容";
if(window.getSelection)
{
selectText=window.getSelection().toString();
}
elseif(document.selection&&document.selection.createRange)
{
selectText=document.selection.createRange().text;
}
if(selectText!=null&&selectText!="")
{
alert(selectText);
}
}
vardivMouseMenu1=document.getElementById("divMouseMenu1");
if(divMouseMenu1!=null)
{
ScriptHelper.addEventListener(divMouseMenu1,"mousedown",mouseMenu1);
}
</script>
</body>
</html>

实例说明:

此实例的代码很多.原理就是通过事件对象判断是否单击了右键,如果是则弹出我们自己的鼠标右键菜单.

六.使用技巧

IE中鼠标左键代码是1,FF是0.IE和FF鼠标右键代码都是2(oEvent.button)
取消默认的鼠标菜单,ie中重写document.oncontentmenu方法,ff中要重写document.click方法.
鼠标事件对象中的clientX和clientY可以获取鼠标的坐标
ie中可以直接设置div的style.top和style.left属性为数字(比如100).ff中必须在数字后加"px"(比如100px)
不同的事件类型有顺序:(1)mousedown(2)mouseup(3)click

七.事件对象详解

获取

IE中,事件对象是window对象的一个属性.事件处理函数必须这样访问事件对象:

obj.onclick=function()
{
varoEvent=window.event;
}


.csharpcode{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
MARGIN:0em
}
.csharpcode.rem{
COLOR:#008000
}
.csharpcode.kwrd{
COLOR:#0000ff
}
.csharpcode.str{
COLOR:#006080
}
.csharpcode.op{
COLOR:#0000c0
}
.csharpcode.preproc{
COLOR:#cc6633
}
.csharpcode.asp{
BACKGROUND-COLOR:#ffff00
}
.csharpcode.html{
COLOR:#800000
}
.csharpcode.attr{
COLOR:#ff0000
}
.csharpcode.alt{
MARGIN:0em;WIDTH:100%;BACKGROUND-COLOR:#f4f4f4
}
.csharpcode.lnum{
COLOR:#606060
}

在DOM标准中,事件对象必须作为唯一参数传给事件处理函数:

obj.onclick=function()
{
varoEvent=arguments[0];
}

除了使用argument[0]访问此参数,我们也可以指定参数名称,上面的代码等同于:

obj.onclick=function(oEvent)
{

}


.csharpcode{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
MARGIN:0em
}
.csharpcode.rem{
COLOR:#008000
}
.csharpcode.kwrd{
COLOR:#0000ff
}
.csharpcode.str{
COLOR:#006080
}
.csharpcode.op{
COLOR:#0000c0
}
.csharpcode.preproc{
COLOR:#cc6633
}
.csharpcode.asp{
BACKGROUND-COLOR:#ffff00
}
.csharpcode.html{
COLOR:#800000
}
.csharpcode.attr{
COLOR:#ff0000
}
.csharpcode.alt{
MARGIN:0em;WIDTH:100%;BACKGROUND-COLOR:#f4f4f4
}
.csharpcode.lnum{
COLOR:#606060
}

目前兼容DOM的浏览器有Firefox,Safari,Opera,IE7等.

通用的事件对象数据

在IE和DOM中,事件对象带有的数据并不完全相同.但是我认为只有完全的那些数据才是值得我们使用的.下面是一些可以在IE和DOM中使用的事件对象数据.其中假设oEvent是事件对象.

1.获取时间类型

vareventType=oEvent.type


2.获取键盘按键代码:

需要在keydown和keyup事件中使用.

vareventKeyCode=oEvent.keyCode


.csharpcode{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
MARGIN:0em
}
.csharpcode.rem{
COLOR:#008000
}
.csharpcode.kwrd{
COLOR:#0000ff
}
.csharpcode.str{
COLOR:#006080
}
.csharpcode.op{
COLOR:#0000c0
}
.csharpcode.preproc{
COLOR:#cc6633
}
.csharpcode.asp{
BACKGROUND-COLOR:#ffff00
}
.csharpcode.html{
COLOR:#800000
}
.csharpcode.attr{
COLOR:#ff0000
}
.csharpcode.alt{
MARGIN:0em;WIDTH:100%;BACKGROUND-COLOR:#f4f4f4
}
.csharpcode.lnum{
COLOR:#606060
}

3.检测Shift,Alt,Ctrl键是否被按下:

varisShift=oEvent.shiftKey;
varisAlt=oEvent.altKey;
varisCtrl=oEvent.ctrlKey;


.csharpcode{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
FONT-SIZE:small;COLOR:black;FONT-FAMILY:consolas,"CourierNew",courier,monospace;BACKGROUND-COLOR:#ffffff
}
.csharpcodePRE{
MARGIN:0em
}
.csharpcode.rem{
COLOR:#008000
}
.csharpcode.kwrd{
COLOR:#0000ff
}
.csharpcode.str{
COLOR:#006080
}
.csharpcode.op{
COLOR:#0000c0
}
.csharpcode.preproc{
COLOR:#cc6633
}
.csharpcode.asp{
BACKGROUND-COLOR:#ffff00
}
.csharpcode.html{
COLOR:#800000
}
.csharpcode.attr{
COLOR:#ff0000
}
.csharpcode.alt{
MARGIN:0em;WIDTH:100%;BACKGROUND-COLOR:#f4f4f4
}
.csharpcode.lnum{
COLOR:#606060
}

返回的是boolean值.

4.获取鼠标指针坐标

varx=oEvent.clientX;
vary=oEvent.clientY;


八.总结

网上复杂绚丽的脚本特效很多,但是再复杂的特效也离不开基础的事件和事件对象.一旦明白了原理,相信大家的创造力可以做出来很多通用的优秀的脚本控件.比如下面这个网址中就有很多的特效:http://www.scriptlover.com/controls/context/,感谢"痴情客"在本系列的第二篇文章中提供了上面的网址.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: