JavaScript事件对象深入详解

所属分类: 网络编程 / JavaScript 阅读数: 1232
收藏 0 赞 0 分享

本文实例讲述了JavaScript事件对象。分享给大家供大家参考,具体如下:

触发 DOM 上的事件时,会生成一个事件对象 event,它包含着所有与事件有关的信息,诸如导致事件的元素、事件的类型以及其他与特定事件相关的信息。所有的浏览器都支持 event 对象,但支持的方式不同。

1 DOM 中的事件对象

兼容 DOM 的浏览器会将 event 对象传入事件处理程序(DOM0 级与 DOM2 级都支持):

var btn = document.getElementById("myBtn");
btn.onclick = function (event) {
 console.log(event.type);//"click"
};
btn.addEventListener("click",function(event){
 console.log(event.type);//"click",false
};

event.type 保存的是被触发的事件类型。

通过 HTML 属性指定事件处理程序时, event 中保存的是 event 对象:

<input type="button" value="Click Me" onclick="alert(event.type)"/>

event 对象包含着创建它的特定事件相关的属性和方法,所以可能每个特定事件都有自己所特有的属性和方法,不过所有事件都会有这些属性和方法:

属性/方法 类型 读/写 说明
bubbles Boolean 只读 事件是否冒泡。
cancelable Boolean 只读 是否可以取消事件的默认行为。
currentTarget Element 只读 与当前事件处理程序相关的元素。
defaultPrevented Boolean 只读 true 表示已调用 preventDefault() 方法(DOM3 新增)。
detail Integer 只读 与事件相关的细节信息。
eventPhase Integer 只读 调用事件处理程序的阶段;1:捕获;2:处于目标;3:冒泡。
preventDefault() Function 只读 取消事件的默认行为(如果 cancelable 为 true,就可以调用这个方法)。
stopImmediatePropagation() Function 只读 阻止事件被进一步捕获或者冒泡,同时阻止任何事件处理程序被调用(DOM3 新增)。
stopPropagation() Function 只读 阻止事件被进一步捕获或者冒泡(如果 bubbles 为 true,就可以调用这个方法)。
target Element 只读 事件的目标。
trusted Boolean 只读 true:事件是由浏览器生成的;false:事件是通过 JavaScript 创建的(DOM3 新增)。
type String 只读 被触发的事件类型。
view AbstractView 只读 与事件相关的抽象视图,相当于发生事件的 window 对象。

在事件处理程序内部,this 始终等于 currentTarget,而 target 等于事件的实际目标。如果直接将事件处理程序指定给目标元素,那么这三个值相等:

<script type="text/javascript">
 var btn = document.getElementById("myBtn");
 btn.onclick = function (event) {
 console.log(event.currentTarget === this);//true
 console.log(event.target === this);//true
 }
</script>

如果事件处理程序指定到按钮的父节点上,那么它们是不同的:

<script type="text/javascript">
 document.body.onclick = function (event) {
 console.log(event.currentTarget === document.body);//true
 console.log(this === document.body);//true
 console.log(event.target === document.getElementById("myBtn"));//true
 }
</script>

如果需要通过一个函数来处理多个事件,那么可以使用 type 属性:

<script type="text/javascript">
 var btn = document.getElementById("myBtn");
 var handler = function (event) {
 switch (event.type) {
  case "click":
  console.log("Clicked");
  break;
  case "mouseover":
  event.target.style.backgroundColor = "red";
  break;
  case "mouseout":
  event.target.style.backgroundColor = "";
  break;
 }
 };
 btn.onclick = handler;
 btn.onmouseover = handler;
 btn.onmouseout = handler;
</script>

使用 preventDefault() 方法来阻止特定事件的默认行为:

<a id="myLink" href="163.com" rel="external nofollow" rel="external nofollow" >点我</a>
<script type="text/javascript">
 var link = document.getElementById("myLink");
 link.onclick = function (event) {
 event.preventDefault();
 }
</script>

注意:只有 cancelable 属性值为 true 的事件,才可以使用 preventDefault() 阻止特定事件的默认行为!

stopPropagation() 会立即阻止事件在 DOM 层次的传播。比如这里在按钮事件中调用 stopPropagation() ,来避免触发注册在 document.body 上的事件处理程序:

<script type="text/javascript">
 var btn = document.getElementById("myBtn");
 btn.onclick = function (event) {
 console.log("Clicked");
 event.stopPropagation();
 };
 document.body.onclick = function (event) {
 console.log("Body clicked");
 };
</script>

eventPhase 属性,可以确定事件当前正处于事件流的哪一个阶段:

<script type="text/javascript">
 var btn = document.getElementById("myBtn");
 btn.onclick = function (event) {
 console.log(event.eventPhase);//2
 };
 document.body.addEventListener("click", function (event) {
 console.log(event.eventPhase);//1
 }, true);//true 表示捕获阶段
 document.body.onclick = function (event) {
 console.log(event.eventPhase);//3
 };
</script>

注意: 只有在事件处理程序执行期间,event 对象才会存在;一旦事件处理程序执行结束,event 对象就会被销毁!

2 IE 中的事件对象

在使用 DOM0 级方法添加事件处理程序时,event 对象是作为 window 对象的一个属性存在:

var btn = document.getElementById("myBtn");
btn.onclick = function () {
 var event = window.event;
 console.log(event.type);//"click"
};

如果是通过 HTML 属性指定的事件处理程序,也跟 DOM一样,可以通过 event 变量来访问 event 对象。

IE 的 event 对象也包含着创建它的特定事件相关的属性和方法,所以可能每个特定事件都有自己所特有的属性和方法,不过所有事件都会有这些属性和方法:

属性 类型 读/写 说明
cancelBubble Boolean 读/写 默认值为 false,true 表示可以取消事件冒泡(同 DOM 的 stopPropagation() )。
returnValue Boolean 读/写 默认值为 true,false 表示取消事件默认行为(同 DOM 的 preventDefault() )。
srcElement Element 只读 事件的目标(同 DOM 中的 target)。
type String 只读 被触发的事件类型。

因为事件处理程序的作用域是根据它指定的方式来确定的,所以最好是使用 event.srcElement 来得到事件的目标比较靠谱:

<button id="myBtn">点我</button>
<script type="text/javascript">
 var btn = document.getElementById("myBtn");
 btn.onclick = function () {
 console.log(window.event.srcElement === this);//true
 };
 btn.attachEvent("onclick", function (event) {
 console.log(event.srcElement === this);//false
 });
</script>

将 returnValue 设置为 false,就能阻止默认行为:

<a id="myLink" href="163.com" rel="external nofollow" rel="external nofollow" >点我</a>
<script type="text/javascript">
 var link = document.getElementById("myLink");
 link.onclick = function () {
 window.event.returnValue = false;
 }
</script>

与 DOM 不同的是,这里没有办法确定事件是否能被取消。

因为 IE 不支持事件捕获,所以只能取消事件冒泡:

<script type="text/javascript">
 var btn = document.getElementById("myBtn");
 btn.onclick = function () {
 console.log("Clicked");
 window.event.cancelBubble = true;
 };
 document.body.onclick = function (event) {
 console.log("Body clicked");
 };
</script>

3 跨浏览器的事件对象

我们把之前的 EventUtil 对象进行增强:

var EventUtil = {
 ...
 /**
 * 返回对 event 对象的引用
 * @param event
 * @returns {*}
 */
 getEvent: function (event) {
 return event ? event : window.event;
 },
 /**
 * 返回事件的目标
 * @param event
 * @returns {*|elem|Object}
 */
 getTarget: function (event) {
 return event.target || event.srcElement;
 },
 /**
 * 取消事件默认行为
 * @param event
 */
 preventDefault: function (event) {
 if (event.preventDefault) {
  event.preventDefault();
 } else {
  event.returnValue = false;
 }
 },
 /**
 * 阻止事件流
 * @param event
 */
 stopPropagation: function (event) {
 if (event.stopPropagation) {
  event.stopPropagation();
 } else {
  event.cancelBubble = true;
 }
 }
}

这样使用:

<button id="myBtn">点我</button>
<script type="text/javascript">
 var btn = document.getElementById("myBtn");
 btn.onclick = function (event) {
 event = EventUtil.getEvent(event);//确保所有浏览器都能使用 event 对象
 var target = EventUtil.getTarget(event);
 console.log(target);
 }
</script>

取消事件默认行为: 

<a id="myLink" href="http://www.163.com" rel="external nofollow" >点我</a>
<script type="text/javascript">
 var link = document.getElementById("myLink");
 link.onclick = function (event) {
 event = EventUtil.getEvent(event);
 EventUtil.preventDefault(event);
 }
</script>

阻止事件传播:

<button id="myBtn">点我</button>
<script type="text/javascript">
 var btn = document.getElementById("myBtn");
 btn.onclick = function (event) {
 console.log("Clicked");
 event = EventUtil.getEvent(event);
 EventUtil.stopPropagation(event);
 };
 document.body.onclick = function (event) {
 console.log("Body clicked");
 };
</script>

因为 IE 不支持事件捕获,所以 EventUtil 的 stopPropagation() 的方法只能阻止事件冒泡。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript事件相关操作与技巧大全》、《JavaScript页面元素操作技巧总结》、《JavaScript操作DOM技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript错误与调试技巧总结

希望本文所述对大家JavaScript程序设计有所帮助。

更多精彩内容其他人还在看

jQuery LigerUI 使用教程表格篇(1)

ligerGrid是ligerui系列插件的核心控件,用户可以快速地创建一个美观,而且功能强大的表格,支持排序、分页、多表头、固定列等等
收藏 0 赞 0 分享

JavaScript中常用的运算符小结

JavaScript中常用的运算符小结,需要的朋友可以参考下。
收藏 0 赞 0 分享

深入理解JavaScript系列(13) This? Yes,this!

在这篇文章里,我们将讨论跟执行上下文直接相关的更多细节。讨论的主题就是this关键字。实践证明,这个主题很难,在不同执行上下文中this的确定经常会发生问题
收藏 0 赞 0 分享

javascript (用setTimeout而非setInterval)

javascript (用setTimeout而非setInterval)如果用setInterval 可能出现 下次调用会在前一次调用前调用
收藏 0 赞 0 分享

JavaScript中两个感叹号的作用说明

用两个感叹号的作用就在于,如果明确设置了o中flag的值(非null/undefined/0""/等值),自然test就会取跟o.flag一样的值;如果没有设置,test就会默认为false,而不是null或undefined
收藏 0 赞 0 分享

javascript写的简单的计算器,内容很多,方法实用,推荐

最近用javascript写了一个简单的计算器,自己测试感觉还好,代码都给了注释,非常不错,推荐大家学习。
收藏 0 赞 0 分享

js的表单操作 简单计算器

javascript写的简单的加减乘除计算器,里面涉及到一些方法还是很实用的哦,新手不要错过
收藏 0 赞 0 分享

Jquery中删除元素的实现代码

empty用来删除指定元素的子元素,remove用来删除元素,或者设定细化条件执行删除
收藏 0 赞 0 分享

javaScript 利用闭包模拟对象的私有属性

JavaScript缺少块级作用域,没有private修饰符,但它具有函数作用域。作用域的好处是内部函数可以访问它们的外部函数的参数和变量(除了this和argument
收藏 0 赞 0 分享

为JavaScript类型增加方法的实现代码(增加功能)

大家在js开发过程中有些功能已经满足不了我们的需求,或没有我们需要的功能,那么我们就可以自己扩展下,个性化js
收藏 0 赞 0 分享
查看更多