作者:约醉 | 来源:互联网 | 2023-05-17 17:36
事件事件:用户与浏览器特定的交互瞬间。事件对象在触发DOM上的事件时,会产生一个事件对象Event,它包含了与事件相关的所有信息。如:事件的类型、导致事件的元素(当前元素)、以及其它与事件相关的信息。
事件
事件:用户与浏览器特定的交互瞬间。
事件对象
在触发DOM上的事件时,会产生一个事件对象Event,它包含了与事件相关的所有信息。如:事件的类型、导致事件的元素(当前元素)、以及其它与事件相关的信息。如鼠标操作事件中,包含了鼠标的位置。键盘操作事件中,包含了是否敲击了键盘等。
DOM中的事件对象
兼容DOM的浏览器会将 事件对象Event 传入事件处理程序中,无论指定事件处理程序的方式是什么(DOM 0级、DOM 2级或HTML特性)。
弹出事件的类型为"click"事件。
对于HTML特性指定的事件处理程序:
在事件处理程序内部,对象this始终等于currentTarget(当前正在处理事件的那个元素),而target表示实际目标(即当前元素)。
当事件处理程序直接指定给input按钮时,
这个例子是直接将事件处理程序指定给了当前元素(即input)。因此this、target、currentTarget这三个值是相等的。
如果事件处理程序在按钮的父节点(如:document.body)中:
第一种情况,当我们直接点击按钮时,
效果:
我们可以看到,当直接点击按钮时,就会在input按钮和document.body上均触发onclick事件。当将事件处理程序指定给input按钮时,currentTarget、this、target的值都是当前元素(input按钮),处理事件的就是input按钮,事件的真正目标是input按钮。当将事件处理程序指定给其document.body时,this === currentTarget,此时处理事件的是document.body,而这个事件的真正目标还是input按钮。
第二种情况,当我们点击input按钮即点击body内部时:效果就不一样了
撑开body
撑开body
效果:
此时,我们可以看到,当点击body内部除input按钮之外的地方时,就会在document.body上触发事件,此时,this===currentTarget===document.body,处理事件的是document.body,注,此时事件的真正目标就是document.body,因为按钮没有触发事件,即e.target===document.body。
有时需要一个函数处理多个事件,因此可以利用 开关语句 为其添加事件。
var input1 = document.getElementById("input1");
var event = function (e) {
switch (e.type) {
case "click":
alert("clicked");
break;
case "mouseover":
e.target.style.color = "red"; //当前元素的颜色变成红色
breadk;
case "mouseout":
e.target.style.color = "blue";
}
};
input1.oclick = event;
input1.mouseover = event;
input1.mouseout = event;
先要判断事件的类型,再执行相应操作。
想要阻止事件的默认行为,可以使用preventDefult()方法来取消事件的默认行为。如:超链接,点击超链接时,会默认跳转到指定的ULR页面。可以用perventDefult()来取消这种行为。
var a1 = document.getElementById("a1");
a1.Onclick= function (e) {
e.preventDefult(); //阻止了a元素默认的跳转行为,点出不会跳转
};
当然,只有cancelable属性的值为true的情况下,才能使用preventDefult()来取消默认的行为。
stopPropagation()停止事件在DOM层次中传播,也就是取消进一步事件捕获或冒泡。
var a1 = document.getElementById("a1");
a1.Onclick= function (e) {
alert("hi");
e.stopProPagation(); //取消事件继续在DOM层次中传播
};
//取消了传播,下列代码不会执行
document.body.Onclick= function (e) {
alert("HI");
};
本来要出现两个警告框的,但通过stopPropagation()已经取消了事件继续在DOM层次中传播,onlcick事件也就不会传播(冒泡)到document.body这里来,因此不会触发注册到document.body上的事件处理程序了,document,body也就不会处理事件了。
eventPhase属性来确定当前事件在哪个阶段了,返回1表示处于捕获阶段,返回2表示事件处理程序处于目标对象上,返回3表示处于冒泡阶段。虽然“处于目标”发生在冒泡阶段,但会返回2。
撑开body
撑开body
效果:
从这个例子中,我们发现,当我们点出按钮时,会触发事件的三个阶段,即第一阶段捕获阶段,第二阶段事件处于目标上,第三阶段冒泡阶段。但当我们点出body内部除了按钮之外的地方时,只会触发事件的二个阶段,分别是第一阶段捕获阶段,第三阶段冒泡阶段,这是因为此时没有点出按钮,那么按钮就不会触发事件处理程序,触发事件的是document.body,也就是说document.body在处理事件,即target===this==currentTarget===document.body。
IE中的事件对象
与访问DOM中的event对象不同的是,IE中访问event对象取决于指定 事件处理程序 的方式(DOM 0级、IE特有的、HTML特性)。在IE中,event对象是未定义的,也就是undefined,返回的是window.event。
使用DOM 0级指定事件处理程序时,event对象是作为window对象的属性来看的。
var input1 = document.getElementById("input1");
input1.Onclick= function () { //
var event = window.event; //全局对象的属性,所以不用传递参数。
alert(event.type); //click
};
可以这样理解:IE中的window.event相当于DOM中的event。且DOM 0级中,IE无需传入event作为参数。
而对于用attachEvent()方法指定事件处理程序,将event对象作为参数传入事件处理函数。
var input1 = document.getElementById("input1");
input1.attachEvent("onclick", function (event) { //传入参数
alert(event.type); //click
});
用这种方法指定事件处理程序,与在DOM中用addEventListener()指定一样,将event对象作为参数传入事件处理函数。
用HTML特性指定事件处理程序,可以通过event变量来访问event对象(与在DOM中用HTML特性指定一样)。
在IE中,用srcElement来表示事件的目标(与DOM中target一样)。
var input1 = document.getElementById("input1");
//DOM 0级方式
input1.Onclick= function () { //在IE中使用DOM 0级,无需传入参数
alert(window.event.srcElement === this); //true
};
在前面已经提过:在IE中通过attachEvent()添加事件,事件处理程序是在全局作用域运行的,也就是this对象指向window对象,属于全局对象。var inpt1 = document.querySelector("#inpt1");
inpt1.attachEvent("onclick", function (e) {
alert(e.srcElement == this); //false 此时this对象指向window对象,事件目标日显不是全局对象。
});
通过attachEvent()方法添加事件,this属于全局对象,指向widow了,不再指向当前元素(inpt1)了,那么srcElement事件目标指向的不是this了,而应该是当前元素(inpt1):var inpt1 = document.querySelector("#inpt1");
inpt1.attachEvent("onclick", function (e) {
alert(e.srcElement == inpt1); //true
});
在IE中,用returnValue来阻止事件的默认行为。与DOM中的perventDefult()方法一样的效果。不过,returnValue要赋值false才有效果。
var input1 = document.getElementById("input1");
//DOM 0级方式
input1.Onclick= function () {
window.event.returnValue = false; //阻止IE中事件的默认行为
};
在IE中,用canceBubble来停止事件在DOM层次中继续传播。与DOM中的stopPropagation()方法一样的效果。不过,要给canceBubble赋值true才有效果。
当然,IE中只有事件冒泡,所以就是停止事件冒泡的继续传播。
var input1 = document.getElementById("input1");
//事件处于目标上阶段
input1.Onclick= function () {
alert("hi");
window.event.canceBubble = true; //停止事件在DOM层次中继续传播,也就是停止事件冒泡。
};
//事件冒泡阶段
document.body.Onclick= function () {
alert("HI");
};
本来要出现两个警告框的,但通过canceBubble已经取消了事件继续在DOM层次中传播,所以,也就不会传播到document.body这是来了。停止通过冒泡触发document.body中注册的事件处理程序。
跨浏览器的事件对象(event)
IE中的event与DOM的event不同,但IE中event对象的全部信息和方法在DOM中也有,所以可以根据它们的相似性做跨浏览器的方法来。将前面提到的EventUtil对象加强即可。
加强后的EventUtil对象:
var EventUtil = {
//添加事件句柄
addHandler : function (element, type, handler) {
//DOM 2级事件处理程序
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) { // IE事件处理程序
element.attachEvent("on" + type, handler);
} else {
//将当前元素看作对象,引用事件处理程序这个属性
element["on" + type] = handler; // DOM 0级事件处理程序
}
},
//获取event对象
getEvent : function (event) {
//利用条件赋值操作符来确定event,如果支持event,则返回DOM中event对象,如果不支持则返回IE中的event对象
return event ? event : window.event
},
//定义getDefult方法,用于阻止事件的默认行为
getDefult : function (event) {
if (event.preventDefult) {
event.preventDefult();
} else {
window.event.returnValue = false;
}
},
//定义getTarget方法,用于获取实际目标
getTarget : function (event) {
return event.target || event.srcElement;
}
//这是删除事件
removeHandler : function (element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null; //DOM 0级删除事件赋值null给事件处理程序名即可。
}
},
//定义stopPropagation方法,用于停止事件继续向DOM层次传播
stopPropagaton : function (event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.canceBubble = true;
}
}
};
在兼容DOM的浏览器中,返回事件对象Eventvar input1 = document.getElementById("input1");
input1.Onclick= function (event) {
event = EventUtil.getEvent(event); //这里返回的是event.
};
在IE中,event是未定义的,也就是undefined,返回的是window.event.var input1 = document.getElementById("input1");
input1.Onclick= function () {
event = EventUtil.getEvent(event); //这里返回的是window.event
};
返回事件目标。var input1 = document.getElementById("input1");
input1.Onclick= function (event) {
var target = EventUtil.getTarget(event);
};
想要返回什么,就可以用EventUtil对象调用其属性即可。是得到event对象,还是阻止默认行为,或者是停止事件的传播均可。
关于Event对象,再多说一句:
在兼容DOM中的Event参数,只是简单地传入和返回;而在IE中的Event参数是未定义的,也就是undefined,返回的是window.event。