Javascript中事件处理的详细解释

第一.事件传播机制

客户端的Javascript程序(这是浏览器)使用异步的事件驱动的编程模型。当一些有趣的事情发生的一个文件,一个浏览器,一个元素,或者一个对象与之关联,Web浏览器生成一个事件(事件)。如果一个Javascript应用关注特定类型的事件,它可以登记一个或更多的功能将被称为当这样的事件发生。当然,这种风格不是Web编程的独特,它是通过使用图形用户界面的所有应用程序使用。

由于要详细处理事件,我们先从几个基本概念开始。

事件类型(事件类型)是用来说明所发生的事件类型字符串。例如,MouseMove指出,用户移动鼠标,和KeyDown表示键盘上的键被按下的事件类型是一个字符串,有时被称为事件的名称。

活动目标(活动目标):一个事件或一个与它相关联的对象。窗口,文件,和元对象是最常见的事件目标。当然,在阿贾克斯XMLHttpRequest对象也是一个事件对象。

事件处理程序(事件处理程序)是一个处理或响应事件的函数,它也称为事件监视器(事件监听器),应用程序通过指示事件类型和事件目标在Web浏览器中注册其事件处理函数。

事件对象(事件对象):一个对象,是一个特定的事件相关,包含有关事件的详细信息。事件对象作为参数传递到事件处理函数(但在IE8及以前的版本中,全局变量事件的事件对象)。事件对象的目标属性指定事件的类型的类型属性(事件类型)和指定的事件对象(事件目标)。但在IE8和其以前的版本,srcelement代替目标。当然,不同类型的事件还可以定义相关的事件对象的其他一些独特的属性。例如,鼠标事件有关的对象将包含鼠标指针的坐标,和键盘事件相关的对象将包含有关按键和辅助键的详细信息。

上述四个基本概念,所以问题是:如果在一个网页上的一个B元素的子元素的鼠标点击,事件处理程序应首先执行B子单元注册或第一个执行元件注册事件处理程序,它(假设一个和B子元素的元素注册事件处理程序)你有没有读过这个问题

这个问题涉及到浏览器中的事件传播机制。我相信每个人都听说过事件冒泡和事件捕获。是的,它们是浏览器中的事件传播机制。怎么会这样呢:


看图片后可能相信您已经了解了浏览器事件传播机制:当事件发生时,它会从上下窗口浏览器对象转移,转移到该事件的触发元素,这是事件捕获过程。该事件从该元素传递到窗口对象,即事件冒泡过程。然而,在IE8及以前的版本中,事件模型中没有定义的捕获过程,只有鼓泡过程。

因此,在上面的问题上,您必须查看元素A注册的事件处理程序是否在捕获过程中或在冒泡过程中。因此,捕获过程中的注册事件处理程序到底是什么,以及在冒泡过程中如何注册事件处理程序这必须讨论注册事件处理程序的方法。

1。将HTML标记属性设置为事件处理程序

文档的元素的事件处理属性,名字是其次的事件的事件的名称如:onclick,onmouseover。当然,这种形式只能登记事件处理程序实例uff1a的DOM元素。






测试

# DIV1 {宽度:300px;身高:300px;背景:红色;溢出:隐藏;}
# DIV2 {保证金:50px汽车;宽度:200px;高度:200px;背景:绿色;溢出:隐藏;}
# div3 {保证金:50px汽车;宽度:100px;身高:100px;背景:蓝色;}



DIV1
格式
div3









结果(在div3区点击鼠标后):


从结果可以看出:

(1)由于HTML不区分大小写,事件处理程序属性名称是大写、小写和混合大小。属性值是相应事件处理程序的Javascript代码。

如果你写了不止一个onclick事件处理属性相同的元素,浏览器只执行代码在第一事件,以及后来的将被忽略;

此窗体是在事件冒泡时注册的事件处理程序;

2。将Javascript对象属性设置为事件处理程序

事件处理程序可以注册事件处理程序通过设置事件对象的事件处理程序属性。事件处理程序的属性的名称是由该事件的事件的名称,如onclick,onmouseover和事件处理程序的名称。uff1a实例






测试

# DIV1 {宽度:300px;身高:300px;背景:红色;溢出:隐藏;}
# DIV2 {保证金:50px汽车;宽度:200px;高度:200px;背景:绿色;溢出:隐藏;}
# div3 {保证金:50px汽车;宽度:100px;身高:100px;背景:蓝色;}



DIV1
格式
div3




VaR DIV1 = document.getelementbyid('div1);
VaR DIV2 = document.getelementbyid('div2);
无功div3 = document.getelementbyid('div3);
div1.onclick =函数(){
console.log('div1);
};
div2.onclick =函数(){
console.log('div2);
};
div3.onclick =函数(){
console.log('div3);
};
div1.onclick =函数(){
console.log('div11111);
};

div1.onclick =函数(){
console.log('div11111);
};






结果(在div3区点击鼠标后):


从结果可以看出:

(1)因为Javascript是严格区分大小写的情况,因此,在这种形式下,属性名只能按照规则小写;

(2)如果我们写多个onclick事件处理属性相同的元素对象,后者将覆盖前面的部分(PS:这是修改对象属性的值,该属性的值是唯一确定的)。

此窗体还在冒泡时注册事件处理过程。

3.addeventlistener()

前两种方式出现在网站的初期,许多浏览器已经实现。addEventListener()方法是在标准事件模型定义。任何对象,可以是一个事件对象包括窗口对象、文档对象、所有的文档元素定义了一个方法调用addEventListener(),可用于登记的事件处理程序的事件对象。(addEventListener)接受三个参数:第一个参数是登记处理的事件类型,其值是一个字符串,但不包括前缀;第二个参数是一个函数的特定类型的事件发生时,应该调用;第三个参数是一个布尔值,可以忽略不计(一些老的浏览器不能忽视此参数),默认值是false。这就是事件处理程序的事件冒泡过程中注册的情况下,当它是真的,事件处理程序的事件捕获过程中的实例uff1a注册。







U3000 U3000
测试
U3000 U3000
# DIV1 {宽度:300px;身高:300px;背景:红色;溢出:隐藏;}
# DIV2 {保证金:50px汽车;宽度:200px;高度:200px;背景:绿色;溢出:隐藏;}
# div3 {保证金:50px汽车;宽度:100px;身高:100px;背景:蓝色;}
U3000 U3000


DIV1
格式
div3
U3000 U3000 U3000 U3000 U3000 U3000
U3000 U3000 U3000 U3000
U3000 U3000

VaR DIV1 = document.getelementbyid('div1);
VaR DIV2 = document.getelementbyid('div2);
无功div3 = document.getelementbyid('div3);
div1.addeventlistener(听到咔哒声,函数(){ console.log('div1-bubble ');},假);
div2.addeventlistener(听到咔哒声,函数(){ console.log('div2-bubble ');},假);
div3.addeventlistener(听到咔哒声,函数(){ console.log('div3-bubble ');},假);
div3.addeventlistener(听到咔哒声,函数(){ console.log('div3-bubble222 ');},假);
div1.addeventlistener(听到咔哒声,函数(){ console.log('div1-capturing ');},真的);
div2.addeventlistener(听到咔哒声,函数(){ console.log('div2-capturing ');},真的);
div3.addeventlistener(听到咔哒声,函数(){ console.log('div3-capturing ');},真的);





结果(在div3区点击鼠标后):


从结果可以看出:

对这第三个参数的函数调用addEventListener()是如上所述。

(2)通过使用addEventListener()方法,我们登记到同一对象的类型的多个事件,不要忽略或覆盖,但执行顺序。

相对addEventListener()()方法,它是removeEventListener也有三个参数,两个参数(addEventListener)与自然的意义,和第三个参数是addEventListener相关(第三)也与参数一致,可以省略,默认值是false,它表明一个事件处理函数从对象实例uff1a删除。


div1.addeventlistener(听到咔哒声,div1bubblefun,假);
div1.removeeventlistener(听到咔哒声,div1bubblefun,假);
功能div1bubblefun(){
console.log('div1-bubble);
}



4.attachevent()

然而,IE8和以前版本的浏览器不支持addEventListener和removeEventListener()(),即定义了类似的方法,attachevent()和()detachevent。因为IE8之前的浏览器不支持事件捕获,attachevent()不能在捕捉过程中登记的事件句柄,所以attachevent()和detachevent()只需要两个参数:事件类型和事件处理函数的第一个参数。此外,使用事件处理程序的属性名称的前缀。实例uff1a




VaR DIV1 = document.getelementbyid('div1);
div1.attachevent('onclick ',div1bubblefun);
功能div1bubblefun(){
console.log('div1-bubble);
}




因此,使用detachevent对象删除事件处理函数(例如):


div1.detachevent('onclick ',div1bubblefun);



到目前为止,我们已经描述了浏览器中事件传播的机制和各种注册事件处理程序的方法。

两。事件处理程序的调用

1,事件处理程序的参数:如前所述,通常事件对象作为参数传递给事件处理程序,但在其之前的浏览器IE8和全局变量的事件是事件的对象。因此,我们要注意兼容性问题,当我们写相关的代码。实例(添加点击事件的元素ID页面上,DIV1当点击元素,输出事件类型和点击的元素本身):






测试

# DIV1 {宽度:300px;身高:300px;背景:红色;溢出:隐藏;}



DIV1

VaR DIV1 = document.getelementbyid('div1);
如果(DIV1。addEventListener){
div1.addeventlistener(听到咔哒声,div1fun,假);
} else if(DIV1。attachevent){
div1.attachevent('onclick ',div1fun);
}
功能div1fun(事件){
事件=事件window.event | |;
VaR目标= event.target event.srcelement | |;
console.log(事件类型);
console.log(目标);
}





2的运行环境。事件处理程序:关于事件处理程序的运行环境,即在事件处理程序中调用上下文(这个值)的方向,我们可以看到以下四个示例。

例1:






测试

# DIV1 {宽度:300px;身高:300px;背景:红色;溢出:隐藏;}



DIV1







结果1:


从结果可以看出:

1。在第一个方法事件处理程序中,这指向元素本身;

例二:






测试

# DIV1 {宽度:300px;身高:300px;背景:红色;溢出:隐藏;}



DIV1

VaR DIV1 = document.getelementbyid('div1);
div1.onclick =函数(){
console.log('div1。框);
console.log(本);
};






结果2:


从结果可以看出:

(1)在第二种事件处理方法中,这也指向元素本身;

当有第二种方法时,它将覆盖由第一个方法注册的事件处理程序;

例三:






测试

# DIV1 {宽度:300px;身高:300px;背景:红色;溢出:隐藏;}



DIV1

VaR DIV1 = document.getelementbyid('div1);
div1.onclick =函数(){
console.log('div1。框);
console.log(本);
};
div1.addeventlistener(听到咔哒声,函数(){(){
console.log('div1。addEventListener:');
console.log(本);
},假);





结果三:


从结果可以看出:

(1)在事件处理的第三种方法中,这也指向元素本身;

这第三种方法不包括由第一种方法或第二种方法注册的事件处理程序;

例四:






测试

# DIV1 {宽度:300px;身高:300px;背景:红色;溢出:隐藏;}



DIV1

VaR DIV1 = document.getelementbyid('div1);
div1.onclick =函数(){
console.log('div1。框);
console.log(本);
};
div1.attachevent('onclick,函数(){(){
console.log('div1。attachevent:');
console.log(=窗口);
});







结果四:


从结果可以看出:

(1)在事件处理的第四种方法中,这指向全局对象窗口;

这第四种方法不包括由第一种方法或第二种方法注册的事件处理程序;

3的呼叫顺序。事件处理程序:多个事件处理程序调用规则如下所示:

(1)HTML属性注册的处理程序和设置对象属性的处理程序首先被调用。

(2)用addEventListener注册的处理程序()是按登记顺序为;

(3)与attachevent注册处理程序()可以以任何顺序调用,所以代码不应该依赖于调用的顺序;

4。活动取消了:

在取消默认浏览器的操作事件(点击超链接元素的默认操作,如将自动跳转页面):如果你使用两个方法注册事件处理程序可以在处理程序添加,返回值false取消默认浏览器运行的事件。在浏览器支持addEventListener(),事件的默认操作,也可以通过调用preventDefault取消()事件对象的方法。至于IE8和之前的浏览器事件的默认行为可以通过设置事件对象的ReturnValue属性是错误的取消。参考代码:




功能cancelhandler(事件){
var =事件| | window.event事件;
如果(事件。preventDefault){
Event.preventDefault();
}
如果(事件中){
event.returnvalue = false;
}
返回false;
}



取消事件传播:支持addEventListener(浏览器),你可以调用里面的事件对象()来防止事件的方法继续蔓延,它可以在传输过程中在事件的任何阶段的工作(捕获阶段,目标事件本身,冒泡阶段);但它不支持的浏览器里面和IE8之前的版本()方法,并捕获阶段,浏览器不支持相应的事件传播,即事件对象有一个cancelbubble属性,此属性设置为true来阻止事件的进一步传播(即防止泡沫)。参考代码(停止点击事件发生在div3地区DIV2和DIV1):






测试

# DIV1 {宽度:300px;身高:300px;背景:红色;溢出:隐藏;}
# DIV2 {保证金:50px汽车;宽度:200px;高度:200px;背景:绿色;溢出:隐藏;}
# div3 {保证金:50px汽车;宽度:100px;身高:100px;背景:蓝色;}



DIV1
格式
div3




VaR DIV1 = document.getelementbyid('div1);
VaR DIV2 = document.getelementbyid('div2);
无功div3 = document.getelementbyid('div3);
div1.onclick =函数(){
console.log('div1);
};
div2.onclick =函数(){
console.log('div2);
};
div3.onclick =函数(事件){
stopeventpropagation(事件);
console.log('div3);
};

功能stopeventpropagation(事件){
var =事件| | window.event事件;
如果(事件。里面){
event.stoppropagation();
其他{ }
event.cancelbubble =真;
}
}





以上是Javascript事件处理的全部介绍。当然,冒泡事件还有一些东西需要学习,这就是我们通常称之为事件代理或事件委托,它将继续更新这方面的知识。