对本地Javascript事件的深入分析

写少做更多的jQuery框架,必然会有更多的原生js。

事实上,我不想写这个博客。看起来像个少年。但我不明白在因特网上绑定和删除原来的JS事件。

首先,这不是很多可以理解的,但我只是想和你分享我的想法。

做事件模型

事件模型的发展,和早期的事件模型称为dom0水平。

dom0事件模型是所有的浏览器都支持。

事件的名称是直接在DOM对象注册,这是由做写的,例如:

复制代码代码如下所示:

document.getelementbyid(测试)。Onclick =功能(e){ };



这意味着登记一个onclick事件。当然,这种写作方式是一种意义:

复制代码代码如下所示:

document.getelementbyid(测试){移动鼠标} =功能(e){ };



这不是什么,访问JS对象属性的方式只有两种,{ }的形式主要是解决属性名不是一个有效的标识符,如:object.123肯定错误,但对象{ 123 }它避免了这个问题,同时,{ }写的,也被JS生活,字符串表示属性名称,你可以运行动态绑定事件。

好了,事件触发了,默认会传递一个参数E,表示事件对象,通过E,我们可以得到很多有用的信息,例如,单击特定的坐标,事件触发的DOM元素等等。

做的事件,对于相同的DOM节点,只能登记一个,并对同一事件的后续注册将覆盖以前的登记。例如:

复制代码代码如下所示:

VaR建立document.getelementbyid(测试);

btn.onmousemove =功能(e){

警报(OK);

};

- {移动鼠标} =功能(e){

警报(1);

};



结果将输出1。

然后讨论这个问题,当事件被触发时,这指的是事件触发了哪个DOM对象:

复制代码代码如下所示:

VaR建立document.getelementbyid(测试);

btn.onmousemove =功能(e){

警报(此id);

};



结果是测试,因为事件是在ID的DOM节点上注册进行测试的。当事件触发时,这表示DOM节点,当然,可以理解这个DOM节点调用事件。

因此,去掉事件非常简单,只需注册一个事件并将值设置为null,例如:

复制代码代码如下所示:

VaR建立document.getelementbyid(测试);

btn.onclick =功能(e){

警报(OK);

};

btn.onclick = null;



原则是在上一个注册事件设置为null之前覆盖最后一个注册事件,并解除事件绑定。

事情还没结束,dom0事件模型还包括,直接写在HTML的事件。例如:

复制代码代码如下所示:





以这种方式注册的事件也遵循覆盖原则,只有一个原则,最后一个是有效的。

不同的是,该注册事件是相当于动态调用函数(一点评价的意思),所以他们不会将事件对象。同时,这指的是窗口,而不是触发事件的DOM对象。

DOM2事件模型

做了比较,DOM2事件模型只懂得以下两点:

DOM2支持相同的DOM元素登记多个相应的事件。

DOM2添加捕获的概念和鼓泡。

DOM2事件通过addEventListener和removeEventListener管理,当然,这是标准的。

但随着IE8浏览器,版本招待,拿出相应的attachevent和detachevent,因为菜才疏学浅不讨论。

注册侦听器,当然,是注册事件。她有三个参数:事件名称比如 uff1a

复制代码代码如下所示:

VaR建立document.getelementbyid(测试);

Btn.addEventListener(单击

警报(OK);

},假);



事件的名称不需要说太多,而做的,除去在前。

事件回调是很好理解的,事件触发了您的全部通知!当回调是做同样的,一个事件的参数介绍,默认情况下,这指的是DOM节点触发事件。

最后一个参数是布尔值,true表示捕获事件,false表示冒泡事件。首先,示意图:



这意味着一个元素触发一个事件。首先要通知的是窗口,然后依次输入文档,直到触发事件(目标元素)的元素实际被捕获。接下来,事件开始从目标元素起泡,然后依次到窗口对象,进程正在冒泡。

你为什么要设计这个This is because of the deep historical roots, the Diamondback is not how to understand, do not talk nonsense.

如您所见,捕获事件是首先触发的,而不是气泡事件。

假设有这样一个HTML结构:

复制代码代码如下所示:









然后我们在外层div上注册两个单击事件,分别是捕获事件和冒泡事件,代码如下所示:

复制代码代码如下所示:

VaR建立document.getelementbyid(测试);

捕获事件

Btn.addEventListener(单击

警报(1);

},真的);

气泡事件

Btn.addEventListener(单击

警报(OK);

},假);



最后,在内层div的点击,首先弹出1,然后弹出OK。结合上述原理图,外部div的图相当于身体。内层div相当于图底部的div。证明了首先执行捕获事件,然后执行冒泡事件。

为什么要强调内层的div因为触发事件的DOM元素必须是内层,而外部DOM元素有机会模拟捕获事件和气泡事件。从原理图上可以看出。

如果您在DOM元素上注册了一个事件和一个冒泡事件,它真的触发了事件

HTML结构是相同的,js代码如下所示:

复制代码代码如下所示:

无功btninner = document.getelementbyid(testinner );

气泡事件

BtnInner.addEventListener(单击

警报(OK);

},假);

捕获事件

BtnInner.addEventListener(单击

警报(1);

},真的);



当然,在内层div点击,结果是第一行,然后1。理论应该捕捉触发事件的第一,这是第一个流行1,但这里是特殊的,因为我们是真正的触发事件注册的DOM元素上的事件,在登记在图DIV是等价的,从图中可以看到真正的触发事件的DOM元素,是捕捉事件的终点,是泡沫事件的起点,因此事件之间没有区别,这是第一个先注册,其中,在这种情况下,泡沫事件先注册,因此首先被执行。

这一原则适用于同一种类的多次事件。例如,一次注册3个气泡,然后按照注册顺序对执行顺序进行注册和执行:

复制代码代码如下所示:

无功btninner = document.getelementbyid(testinner );

BtnInner.addEventListener(单击

警报(OK);

},假);

BtnInner.addEventListener(单击

警报(1);

},假);

BtnInner.addEventListener(单击

警报(ok2 );

},假);



其结果是,当然,好的,1,ok2。

为了进一步理解事件模型,还有另外一个场景。如果外层的div和内层div登记同时捕获的事件,那么外层的div的事件必须首先触发点击内层div的时候

复制代码代码如下所示:

VaR建立document.getelementbyid(测试);

无功btninner = document.getelementbyid(testinner );

BtnInner.addEventListener(单击

警报(OK);

},真的);

Btn.addEventListener(单击

警报(1);

},真的);



结果是,1是冒出来的第一个。

如果外层div和内层div都是已注册的冒泡事件,那么单击内部div必须是内部div事件的第一个执行和同样的原则。

细心的读者会发现,对于div嵌套的案例,如果您点击内层的div,外部div会触发一个事件,这似乎是个问题!

单击清晰地是内部div,但外部div的事件被触发,这是一个问题。

事实上,当一个事件被触发时,它将默认地传递给事件对象。在这之前,在这个事件对象的方式:里面,通过这种方式,它可以阻止泡沫,所以外层的div不会接收事件,代码如下:

复制代码代码如下所示:

VaR建立document.getelementbyid(测试);

无功btninner = document.getelementbyid(testinner );

Btn.addEventListener(单击

警报(1);

},假);

BtnInner.addEventListener(单击

停止/冒泡

e.stoppropagation();

警报(OK);

},假);



最后,我们不得不说,如何摆脱事件。释放事件语法:btn.removeeventlistener(事件名称

这与绑定事件的参数相同,详细说明了这一点。

事件的名称是说哪个事件被解除。

事件的回调函数必须与已注册事件的函数相同。

事件类型,布尔值,它必须与注册事件的类型相一致。

也就是说,名称,类型,回调,三方决定解散的事件联系在一起。例如 uff1a

复制代码代码如下所示:

VaR建立document.getelementbyid(测试);

回调存储在变量中。

函数(e){

警报(OK);

};

绑定

Btn.addEventListener(单击

电梯

Btn.removeEventListener(单击



如果可以删除已注册事件,则必须保存回调函数,否则无法删除。

Dom0和DOM2

事情一直很混乱,这是一个混合使用,而不是让人们生活。

别害怕,混合使用绝对没有问题。dom0模型和DOM2模型按照自己的规则,互不影响。

总的来说,第一个注册,第一个执行,剩下的什么也不是。

后记

此时,本机js事件大致相同。菜肴只知道这一点,并欢迎读者添加到其他的知识点。

在实际应用中,注册真的专家不傻那么多的活动,在正常情况下,只需要登记在DOM元素的最外层的一个事件,然后通过捕获和冒泡机制找到真正引发DOM元素事件,根据DOM元素触发事件提供的信息来调用回调。

也就是说,专家可以自己管理事件,而不是依靠浏览器来管理它们,这可以提高效率并确保兼容性。jQuery不这样做。

好了,这是本教程的结尾,希望对读者有所帮助!