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

Javascript
JavaScript DOM学习第八章 表单错误提示
JavaScript DOM 学习第九章 选取范围的介绍
JavaScript CSS修改学习第一章 查找位置
JavaScript CSS修改学习第二章 样式
JavaScript CSS修改学习第三章 修改样式表
JavaScript CSS 修改学习第四章 透明度设置
JavaScript CSS修改学习第五章 给“上传”添加样式
JavaScript CSS修改学习第六章 拖拽
Jquery乱码的一次解决过程 图解教程
javascript 包裹节点 提高效率
javascript inneHTML的地雷
javascript 定义新对象方法
判定对象是否为window的js代码
jquery validator 插件增加日期比较方法
jquery 得到当前页面高度和宽度的两个函数
JavaScript 编写匿名函数的几种方法
jQuery 操作下拉列表框实现代码
jQuery入门问答 整理的几个常见的初学者问题
第一个JavaScript入门基础 document.write输出
javascript入门基础之私有变量

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-12   浏览: 110 ::
收藏到网摘: 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........