本文深入解析JavaScript中DOM事件对象event的核心属性与方法。详细阐述target、currentTarget与this的区别,说明type、timeStamp等标准属性的用法,并演示preventDefault()与stopPropagation()的实际应用。结合代码示例,清晰展示事件从捕获到冒泡的完整生命周期及eventPhase的阶段判定。
事件对象概述
当DOM元素上触发特定事件时,系统会自动生成一个事件对象event。
DOM中的事件对象
符合DOM标准的浏览器会将event对象作为参数传递给事件处理程序。该对象包含了与引发它的具体事件相关的属性和方法。由于事件类型不同,可用的属性和方法也会有所差异,但所有事件均具备下表列出的通用成员。
事件对象的标准属性
以下列出了2级DOM事件标准中定义的属性:
- bubbles:返回布尔值,用于指示该事件是否属于起泡事件类型。
- cancelable:返回布尔值,用于指示该事件是否允许取消默认动作。
- currentTarget:返回注册了事件监听器的当前元素,即触发该事件监听器的元素。
- eventPhase:返回事件当前所处的传播阶段。
- target:返回触发该事件的实际元素(即事件的目标节点)。
- timeStamp:返回事件发生时的日期和时间戳。
- type:返回当前Event对象所表示的事件名称。
事件对象的标准方法
以下列出了2级DOM事件标准中定义的方法。需要注意的是,IE的事件模型不支持这些方法:
- initEvent():用于初始化新创建的Event对象的属性。
- preventDefault():通知浏览器不要执行与该事件关联的默认动作。
- stopPropagation():用于停止事件的进一步派发。
this、target与currentTarget的区别
this、target、currentTarget
在事件处理程序内部,this始终等于currentTarget的值,而target仅包含事件的实际目标元素。如果直接将事件处理程序绑定到目标元素上,那么this、currentTarget和target三者的值是相同的。例如:
var btn = document.querySelector("#btn");
btn.onclick=function () {
console.log(event.currentTarget === this); //true
console.log(event.target === this); //true
}
由于click事件的目标是btn按钮,因此上述三个变量指向相同的对象。若事件处理程序绑定在按钮的父节点(如document.body)上,则这三个值将不再相同。例如:
var btn = document.querySelector("#btn");
document.body.onclick=function () {
console.log(event.currentTarget === document.body); //true
console.log(this === document.body); //true
console.log(event.target === btn); //true 因为btn没有注册事件处理程序,所以该click事件就冒泡到了document.body
}
在此场景中,this和currentTarget均指向document.body,因为事件处理程序是注册在该元素上的。然而,target指向按钮元素,因为它是click事件的真正发起者。由于按钮本身未注册事件处理程序,click事件通过冒泡机制传递到了document.body,从而在那里得到处理。
利用type属性处理多事件
type
当需要通过同一个函数处理多种事件时,可以利用type属性进行判断。例如:
//获取按钮
var btn = document.querySelector("#btn");
//设置多个事件
var handler = function() {
//检测事件的类型
switch (event.type) {
case "click":
console.log("i click it");
break;
case "mouseover":
console.log("i enter it");
break;
case "mouseout":
console.log("i leave it");
break;
}
}
//给响应的事件赋值
btn.onclick = handler;
btn.onmouseover = handler;
btn.onmouseout = handler;
preventDefault()
阻止默认行为preventDefault
若要阻止特定事件的默认行为,可调用相应方法。例如:
var aTags = document.getElementsByTagName("a");
for (var i = 0; i < aTags.length; i++) {
var currentATag = aTags[i];
currentATag.onclick = function() {
event.preventDefault();
}
};
上述代码屏蔽了网页中所有a标签的超链接功能。需注意,只有当cancelable属性为true的事件,才能使用preventDefault()来取消默认行为。
停止事件传播stopPropagation
stopPropagation()
该方法用于立即停止事件在DOM层级中的传播,从而取消后续的事件捕获或冒泡。例如,若直接在按钮上添加事件处理程序并调用此方法,即可避免触发注册在document.body上的事件处理程序。例如:
var btn = document.getElementById("btn");
btn.onclick = function () {
console.log("btn clicked");
// event.stopPropagation();
};
window.onclick = function () {
console.log("clicked");
};
//单击一下的结果:
//btn clicked
//clicked
再如:
var btn = document.getElementById("btn");
btn.onclick = function () {
console.log("btn clicked");
event.stopPropagation();
};
window.onclick = function () {
console.log("clicked");
};
//单击一下的结果:
//btn clicked
事件阶段eventPhase解析
eventPhase
该属性用于确定事件当前正处于事件流的哪个阶段。
具体数值含义如下: 1、若处于捕获阶段,值为1; 2、若处于目标对象阶段,值为2; 3、若处于冒泡阶段,值为3; 例如:
var btn = document.getElementById("btn");
document.body.addEventListener("click", function() {
console.log("bodyListener" + event.eventPhase);
}, true) //捕获阶段
btn.onclick = function() {
console.log("btn" + event.eventPhase);
} //目标对象阶段,实际上属于冒泡阶段(在btn上)
document.body.onclick = function() {
console.log("body" + event.eventPhase);
} //冒泡阶段(在body上)
再如:
var btn = document.getElementById("btn");
document.body.addEventListener("click", function() {
console.log(event.eventPhase); //1
console.log(event.currentTarget); //HTMLBodyElement
}, true);
btn.addEventListener("click", function() {
console.log(event.eventPhase); //2
console.log(event.currentTarget); //HTMLInputElement
});
document.body.addEventListener("click", function() {
console.log(event.eventPhase); //3
console.log(event.currentTarget); //HTMLBodyElement
});
执行流程大致如下:
document.body 捕获阶段 --> btn 目标对象阶段 --> document.body 冒泡阶段
以上内容即为关于JavaScript事件对象event的完整解析,希望能为读者提供有益的帮助。