当前位置: 首页 > 图文教程 > 网络编程 > Javascript > Javascript拖拽&拖放系列文章3之细说事件对象

Javascript
xp风格菜单
具有edit功能的combobox
可以编辑的Select (第二版)
IE6.0打印机制解析
JScript5.5下String.prototype.replace(str,func)的UBB嵌套的递归解开。
vbscript和javascript互相调用方法
转换大写中文数字
Freeonline在线编辑器(自由软件)
对象化JS之----文件上传客户端控制脚本
对象化JS之----日期选择
对象化JS之----仿outlook或者QQ的菜单
如何使用Shell.Application技术
模拟windows control的进度条
双向链表&&堆栈
网页中的媒体播放器
如何在页面显示来访者分辨率,浏览器(js)
子父窗口之间的操作之小例子
JavaScript 实现日历式日期选择
页面上的javascript判断
在客户端用JAVASCRIPT或VBSCRIPT生成WORD文档

Javascript拖拽&拖放系列文章3之细说事件对象


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-12   浏览: 103 ::
收藏到网摘: n/a

Javascript中的事件对象其实和.NET中继承自EventArgs类的派生类类似,用来给事件处理程序传递状态信息,从而进行相应的操作。这一篇文章将讲述Javascript事件对象中和实现拖拽功能相关的几个属性,并在最后将IE事件模型和标准DOM事件模型的差异封装到一个类中,从而适应所有的浏览器。 在阅读本文前,可以先阅读《Javascript拖拽&拖放系列文章2之offsetLeft、offsetTop、offsetWidth、offsetHeight属性》这篇文章,以理清上下文关系。
好了,让我们开始进入正题。
模型相同的属性/方法
1 Button属性
Integer类型,可读可写。对于特定的鼠标事件,表示按下的鼠标按钮,它可以在拖拽的时候,判断是否是鼠标左键引发mousedown事件。它的所有取值及其意义(参考自《Javascript高级程序设计》)好了,让我们开始进入正题。
3.1 e/window.Event对象的属性/方法
3.1.1 IE事件模型和DOM事件如下:
0-未按下按钮
1-按下左键
2-按下右键
3-同时按下左右按钮
4-按下中键
5-按下左键和中键
6-按下右键和中键
7同时按下左中右键
mouseup的button属性返回的数值和mousedown事件中的完全一样。
注:在兼容DOM事件模型的所有浏览器中,0表示按下左键,数值1并不存在,2表示按下右键,对于非鼠标事件,返回“undefined”。
2 clientX、clientY属性
这两个属性的类型都是Integer,单位是像素,可读可写。分别表示相关事件发生时,鼠标在浏览器的客户端区域(不包括工具栏、滚动条等)的x坐标和y坐标。用一张图片来解释就再好不过了,请看:

图3.1:clientX和clientY属性

以下代码是一个非常简单的示例,它可以随时定位鼠标的坐标,并将结果显示在两个文本框中,如果愿意的话,你可以尝试运行它,兼容目前所有的现代浏览器。

示例代码1:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<style type="text/css">
body
{
border
:1px solid black;
margin
:0px;
}
</style>
<script type="text/javascript" language="JavaScript">
document.onmousemove
=move;
function move(e){
if(!e)
{
e
=window.event;
}
var xElement=document.getElementById("x");
var yElement=document.getElementById("y");
xElement.value
=e.clientX;
yElement.value
=e.clientY;
}
</script>
</head>
<body>
<input type="text" id="x" value="" />
<input type="text" id="y" value="" />
</body>
</html>



3 type属性
Javascript中的事件对象其实和.NET中继承自EventArgs类的派生类类似,用来给事件处理程序传递状态信息,从而进行相应的操作。这一篇文章将讲述Javascript事件对象中和实现拖拽功能相关的几个属性,并在最后将IE事件模型和标准DOM事件模型的差异封装到一个类中,从而适应所有的浏览器。
String类型,在IE中可读可写,而在兼容DOM事件模型的浏览器中为只读属性。

3.2 将IE事件模型和DOM事件模型的差异封装起来

注:本来打算采用《Javascript高级程序设计》这本书中所叙述的方法来封装差异,读过的人知道,作者是用return EventUtil.getEvent.caller.Arguments[0]来获得原始的事件对象的,这的确很棒,很巧妙,已经很完美了,我没有必要在re-invent the wheel了,只可惜Opera浏览器不支持caller属性,为了浏览器兼容性,所以我不得不采用自己的方法了。caller的详细内容可以参考全面理解JavaScript中的caller,callee,call,apply 这篇文章

3.2.1 定义框架

首先定义一个封装的框架,再细细添枝加叶。

var EventUtilization=new Object;
EventUtilization.getCompatibleEvent
=function(e){
//判断是否是IE浏览器
if(!EventUtilization.getCompatibleEvent.arguments[0])
{
e
=window.event;
//使IE的window.event属性和DOM的一样
//..
return e;
}
return e;
}

3.2 将IE事件模型和DOM事件模型的差异封装起来

注:本来打算采用《Javascript高级程序设计》这本书中所叙述的方法来封装差异,读过的人知道,作者是用return EventUtil.getEvent.caller.Arguments[0]来获得原始的事件对象的,这的确很棒,很巧妙,已经很完美了,我没有必要在re-invent the wheel了,只可惜Opera浏览器不支持caller属性,为了浏览器兼容性,所以我不得不采用自己的方法了。caller的详细内容可以参考全面理解JavaScript中的caller,callee,call,apply 这篇文章

3.2.1 定义框架

首先定义一个封装的框架,再细细添枝加叶。

var EventUtilization=new Object;
EventUtilization.getCompatibleEvent
=function(e){
//判断是否是IE浏览器
if(!EventUtilization.getCompatibleEvent.arguments[0])
{
e
=window.event;
//使IE的window.event属性和DOM的一样
//..
return e;
}
return e;
}

很简单,就不再赘述了。

3.2.2 格式化window.Event对象

1 构造DOM中的pageX和pageY属性

这两个属性分别表示鼠标指针相对于整张网页(取决于body元素的实际边界范围)的x、y坐标,单位是像素。在构造它们之前,需要了解另外两个属性document.Body.scrollLeft和document.body.scorllTop,单位是像素,当浏览器出现滚动条且滚动页面时,数值分别等同于页面在水平、垂直方向上滚动的距离,否则为0像素。

我想你已经想到了该如何构造pageX和pageY了。没错,pageX=clientX+scorllLeft,pageY=clientY+clientTop。

Javascript代码片段:

 if(!EventUtilization.getCompatibleEvent.arguments[0])
{
e
=window.event;
e.pageX
=e.clientX+document.body.scrollLeft;
e.pageY
=e.clientY+document.body.scrollTop;
//..
}

2 构造DOM中的relatedTarget属性

我们可以用事件对象的type属性判断鼠标事件类型,从而决定何时将fromElement或toElement的值赋给relatedTarget属性。

Javascript代码片段:

 if(!EventUtilization.getCompatibleEvent.arguments[0])
{
e
=window.event;
//..
if(e.type=="mouseout")
{
e.relatedTarget
=e.toElement;
}
else if(e.type=="mouseover")
{
e.relatedTarget
=e.fromElement;
}
//..
}

3 构造DOM中的target/currentTarget属性

终于快要结尾了......

只需要引用srcElement属性就可以了,不过要注意,我们在前面说过,在mouseout事件中,DOM的target总是等于relatedTarget属性,因此我们同样要构造currentTarget属性,以免在调用currentTarget时返回“undefined”。

 if(!EventUtilization.getCompatibleEvent.arguments[0])
{
e
=window.event;
//..
e.target=e.srcElement;
e.currentTarget
=e.srcElement;
//..
}

完整的JS代码:


var EventUtilization=new Object;
EventUtilization.getCompatibleEvent
=function(e){
if(!EventUtilization.getCompatibleEvent.arguments[0])
{
e
=window.event;
e.pageX
=e.clientX+document.body.scrollLeft;
e.pageY
=e.clientY+document.body.scrollTop;
if(e.type=="mouseout")
{
e.relatedTarget
=e.toElement;
}
else if(e.type=="mouseover")
{
e.relatedTarget
=e.fromElement;
}
e.target
=e.srcElement;
e.currentTarget
=e.srcElement;
return e;
}
return e;
}

它能够完美的兼容Internet Explorer、Mozilla Firefox、Netscape、Sarari(Chrome)、Opera等浏览器的流行版本。

3.2.3 框架的使用

我将它命名为EventUtilization.js,将它放在页面中后,就可以用如下的方法使用了:

 var source=document.getElementById("mouseoverElement");
source.onmouseover
=function(e){
var e=EventUtilization.getCompatibleEvent(e);
alert(e.pageX);
alert(e.pageY);
alert(e.relatedTarget.tagName);
alert(e.target.tagName);
alert(e.currentTarget.tagName);
};

啊,冗长的一篇文章被我写完了,我终于可以休息一下了........希望能给一些人帮助,哪怕是一点点,也会是我继续写下去的动力........

至于下一篇写什么?卖个关子先。

To be continued........