JavaScript之DOM事件模型

来源:互联网 发布:交友聊天软件 编辑:程序博客网 时间:2024/06/06 08:41

EventTarget接口

addEventListener:绑定事件的监听函数

target.addEventListener(type,listener,useCapture)

var btn=document.getElementById('btn');btn.addEventListener('click',hello,false);function hello(){console.log('ok');}

addEventListener方法可以为当前对象的同一个事件,添加多个监听函数。这些函数按照添加顺序触发,即先添加先触发。
如果为同一个事件多次添加同一个监听函数,该函数只会执行一次,多余的添加将自动被去除。
false:监听函数只在冒泡阶段被触发;
true:监听函数只在捕获阶段被触发

removeEventListener:移除事件的监听函数

removeEventListener方法移除的监听函数,必须与对应的addEventListener方法的参数完全一致,而且必须在同一个元素节点,否则无效。

box.removeEventListener('click', hello2, true);

dispatchEvent:触发事件

只要有一个监听函数调用了Event.preventDefault(),则返回值为false,否则为true。

var box=document.getElementById('box');box.addEventListener('click',hello,true);box.addEventListener('click',hello2,true);function hello(){console.log('ok');}function hello2(){console.log('ok');}var click=new Event('click');box.dispatchEvent(click);//ok//ok

监听函数

事件发生时,程序所要执行的函数。

HTML标签的on-属性

<div onclick="console.log('ok');console.log('ok2');"></div><div onclick="hello()"></div>//正确,应该传入执行的代码,而不是函数<div onclick="hello"></div>//错误<script>function hello(){console.log('ok');}</script>

使用这个方法指定的监听函数,只会在冒泡阶段触发。

function hello(){console.log('ok');}var box=document.getElementById('box');box.setAttribute('onclick','hello()');//同上

Element节点的事件属性

div.onclick = function(event){  console.log('触发事件');};

同一个事件只能定义一个监听函数,也就是说,如果定义两次onclick属性,后一次定义会覆盖前一次。
使用这个方法指定的监听函数,只会在冒泡阶段触发。

addEventListener方法

推荐

this对象的指向

addEventListener方法指定的监听函数,内部的this对象总是指向触发事件的那个节点。因为监听函数被“拷贝”成了节点的一个属性,所以this指向节点对象。

var box=document.getElementById('box');box.onclick=hello;box.addEventListener('click', hello, false);function hello(){    console.log(this); }//box//box

如果将监听函数部署在Element节点的on-属性上面,this不会指向触发事件的元素节点。

<div onclick="hello()"></div><div id="box2"></div><script>function hello(){    console.log(this); }var box2=document.getElementById('box2');box2.setAttribute('onclick','hello()');//window//window//相当于 box2.onclick=function(){hello();}</script>

一种解决方法是,不引入函数作用域,直接在on-属性写入所要执行的代码。因为on-属性是在当前节点上执行的。

<div id="box"onclick="console.log(id);console.log(this.id)"></div>//box//box

事件的传播

一个事件发生后,会在不同的DOM节点传播。

主流浏览器支持标准的DOM事件处理模型:捕获型与冒泡型。

分成三个阶段:
捕获阶段:从window对象传导到目标节点;
目标阶段:在目标节点触发;
冒泡阶段:从目标节点传导到window对象。

<div id="p">    <div id="c"></div></div>var c=document.getElementById('c');var p=document.getElementById('p');c.addEventListener('click', function(){console.log('c')}, true);p.addEventListener('click', function(){console.log('p')}, true);c.addEventListener('click', function(){console.log('c2')}, false);p.addEventListener('click', function(){console.log('p2')}, false);//点击内部的div//p   捕获阶段//c   目标阶段//c2  目标阶段//p2  捕获阶段

传播途径:window-document-html-body-…- body-html-document-window

IE使用自己的模型:冒泡型。

IE9以下不支持addEventListener()函数,IE9以上(包括IE9)支持,IE浏览器相应的要使用attachEvent()函数代替,它支持全系列的IE,但Chrome浏览器不支持attachEvent()。
ele.attachEvent(“onclick”, doSomething);

事件代理/事件委托

由于事件会传导到父节点,所以可以将监听函数定义在父节点上,由父节点统一处理多个子元素的事件。

var ul=document.querySelector('ul');ul.onclick=function(event){    if(event.target.tagName.toLowerCase()==='li'){console.log(event.target);}}

stopPropagation:使事件到当前节点为止,不再传播

<div>    <p>riuoweurew</p></div>var li=document.querySelector('p');var ul=document.querySelector('div');li.addEventListener('click', hello1, false);ul.addEventListener('click', hello2, false);//不会触发function hello1(e){console.log('hello1');e.stopPropagation();}function hello2(){console.log('hello2');}//点击p//hello1

但是,stopPropagation方法只会阻止当前监听函数的传播,不会阻止该节点上的其他click事件的监听函数。如果想要不再触发那些监听函数,可以使用stopImmediatePropagation方法。
stopImmediatePropagation方法阻止同一个事件的其他监听函数被调用。
如果同一个节点对于同一个事件指定了多个监听函数,这些函数会根据添加的顺序依次调用。只要其中有一个监听函数调用了stopImmediatePropagation方法,其他的监听函数就不会再执行了。

var li=document.querySelector('p');var ul=document.querySelector('div');li.addEventListener('click', hello1, false);li.addEventListener('click', hello2, false);//会触发ul.addEventListener('click', hello2, false);function hello1(e){console.log('hello1');e.stopPropagation();}function hello2(){console.log('hello2');}//点击p//hello1//hello2  li上触发的click//使用stopImmediatePropagationvar li=document.querySelector('p');var ul=document.querySelector('div');li.addEventListener('click', hello1, false);li.addEventListener('click', hello2, false);//不会触发ul.addEventListener('click', hello2, false);function hello1(e){console.log('hello1');e.stopImmediatePropagation();}function hello2(){console.log('hello2');}//点击p//hello1

Event对象

event =new Event(名称,配置)
配置是一个对象,有两个属性,bubbles表示是否冒泡,cancelable表示是否可取消

var ev=new Event('look',{bubbles:true,cancelable:false});document.addEventListener('look', function(){console.log('ok');}, false);document.dispatchEvent(ev);//ok

event.bubbles:返回布尔值,表示是否会冒泡

event.eventPhase:返回整数,表示事件发生的阶段

0:还没发生
1:捕获阶段
2:目标阶段
3:冒泡阶段

event.cancelable:返回布尔值,表示事件是否可以取消

var ev=new Event('look',{bubbles:true,cancelable:false});document.addEventListener('look', function(e){    console.log(e.cancelable,e.bubbles,e.eventPhase,e.target,e.currentTarget);}, false);document.dispatchEvent(ev);//false true 2 document document

event.defaultPrevented:返回布尔值,表示是否调用了preventDefault方法

event.target:返回事件发生的节点,事件最初发生的节点

event.currentTarget:正在执行的监听函数所绑定的那个节点。

在监听函数中,currentTarget属性实际上等同于this对象。

var p=document.querySelector('p');var div=document.querySelector('div');p.addEventListener('click', function(e){    console.log(e.cancelable,e.bubbles,e.eventPhase,e.target,e.currentTarget,e.defaultPrevented);        }, false);div.addEventListener('click', function(e){console.log(e.cancelable,e.bubbles,e.eventPhase,e.target,e.currentTarget,e.defaultPrevented);}, false);//点击p//true true 2 p p false//true true 3 p div falsevar p=document.querySelector('p');var div=document.querySelector('div');p.addEventListener('click', function(e){    e.preventDefault();    console.log(e.cancelable,e.bubbles,e.eventPhase,e.target,e.currentTarget,e.defaultPrevented);        }, false);div.addEventListener('click', function(e){console.log(e.cancelable,e.bubbles,e.eventPhase,e.target,e.currentTarget,e.defaultPrevented);}, false);//点击p//true true 2 p p true//true true 3 p div true

e.type:事件类型,e.detail:事件信息,e.timeStamp:事件发生时间戳,e.isTrusted:是否人为触发

var p=document.querySelector('p');var div=document.querySelector('div');p.addEventListener('click', function(e){    console.log(e.type,e.detail,e.isTrusted,e.timeStamp);}, false);div.addEventListener('click', function(e){    console.log(e.type,e.detail,e.isTrusted,e.timeStamp);}, false);//click 1 true  177572//click 1 true  177572

对于dblclick事件,detail属性的值总是2

e.preventDefault()

取消浏览器对当前事件的默认行为,比如点击链接后浏览器跳转到指定地址,或者按一下空格键,页面滚动一段距离,该方法生效的前提是cancelable为true。
该方法与stopPropagation()不同。

自定义事件

var event=new Event('build');elem.addEventListener('build',function(e){},false);elem.dispatchEvent(event);

Event构造函数只能指定事件名,不能在事件上绑定数据。如果需要在触发事件的同时,传入指定的数据,需要使用CustomEvent构造函数生成自定义的事件对象。

var elem=document.querySelector('a');var event=new CustomEvent('build',{detail:'helloworld'});elem.addEventListener('build',function(e){console.log(e.detail);},false);elem.dispatchEvent(event);//helloworld
1 0
原创粉丝点击