JS学习笔记——事件

来源:互联网 发布:网络约车平台架构图 编辑:程序博客网 时间:2024/06/08 04:07

1.事件流

当我们点击网页上的某一个元素时,触发的动作不仅仅跟这个元素有关,还跟包含这个元素的所有上层容器有关。触发事件流的流动有一个先后顺序,目前有两种:1.IE所提出的事件冒泡;2.Netscape所提出的事件捕获。
DOM事件流则是综合了前面两种事件流,先捕获再冒泡。现代浏览器大多支持DOM事件流。



2.事件处理程序

为元素绑定相应的事件处理程序有3种方法:HTML、DOM0级、DOM2级。事件处理程序以”on”开头,如”click”事件的处理程序是”onclick()”。

2.1 HTML事件处理

我们把事件处理程序当做html的元素属性加入html标签中。这种方法的最大缺点就是html和js紧耦合。

<input type="button" value="button" onclick="alert(`Click Me`)" /><input type="button" value="button" onclick="test()" /><script>function test() {    //...}</script>

2.2 DOM0级事件处理

通过DOM操作获取元素,元素都带有事件处理(比如onclik())的属性,我们把函数赋值给该属性即可。在事件处理程序中,this指向给调用该事件处理程序的元素(在事件委托中,this就指向那个尽量高层次的元素)。若想删除事件处理程序,将该属性赋值null即可。DOM0级绑定的事件处理程序会发生在冒泡阶段。

var p = document.getElementById('p');p.onclick = function() {    alert(this.id);//p}p.onclick = null;//删除绑定的事件处理程序

2.3 DOM2级事件处理

DOM2级事件处理程序的功能比DOM0级更加丰富。DOM2级可以一个事件添加多个处理程序,还可以指定程序在冒泡阶段调用还是捕获阶段调用。DOM2级要删除处理程序,需要传入添加函数时的那个函数参数,这就说明,添加的匿名函数无法删除。

var p = document.getElementById('p');p.addEventListener("click", function(){    alert(this.id);//p}, false);//第三个参数 true:捕获阶段调用;false:冒泡阶段调用;//该移除函数没有起作用p.removeEventListener("click", function(){    alert(this.id);}, false);

2.4 IE事件处理

虽然IE9也支持DOM2级事件处理程序(DOM事件流),但在IE9以前,是只支持IE事件处理(IE事件流)的。IE事件流是事件冒泡。IE事件处理程序与DOM2级事件处理程序非常相似。IE事件处理只支持两个参数,第三个参数无法选择捕获还是冒泡。在IE8以及更早版本中,只支持冒泡。与DOM2级不同的是,这里的this指向全局window。
这里我们注意,并不是所有IE浏览器都是IE事件处理(IE事件流),像IE9就支持DOM事件流,支持DOM事件流,也支持DOM2级事件处理程序。

var p = document.getElementById('p');p.attachEvent("onclick", function(){//注意这里是"onclick",而不是DOM2级的"click"    alert(this === window);//true});//与DOM2级一样,匿名函数无法被删除p.detachEvent("onclick", function(){    alert(this === window);//true});

3.DOM事件对象

事件对象分为DOM事件对象和IE事件对象,IE就是个奇葩的存在,除了IE之外,其他浏览器都是DOM事件对象。
事件处理程序会接收一个事件对象,该事件对象中有许多跟事件有关的属性,比如type、churentTarget、target等。
下面我们区分一下三个容易混淆的属性thistargetcurrentTarget。this始终等于currentTarget,这两个又等于调用处理程序的元素。target等于动作真实发生的对象。

<body>    <div id='div'>        <p id='p'>hello!</p>    </div></body>//div是p的父元素,如果点击p,event.target就是p//如果点击div其他地方(不是p),event.target就是divdiv.detachEvent("onclick", function(event){    //event.type == "click"    alert(this === div);//true    alert(event.currentTarget === div);//true    alert(event.target === p);//true});

4.事件代理(事件委托)

如果我们有许多的元素需要绑定事件处理程序,按照上面的方法:先使用DOM获取元素,再给元素绑定函数。这种方法会使得web性能下降:DOM操作耗时;函数的本质是对象,耗内存。
这种场景的解决方法就是使用事件代理,即利用事件冒泡,给尽量高层次的元素绑定一个事件,在这个事件中,根据事件对象的属性来做相应的处理。

div.onclick = function(event) {    switch(event.target.id) {        case 'p':            alert('p');            break;        case 'div':            alert('div');            break;    }}
0 0
原创粉丝点击