事件
DOM事件机制,就是通过监听函数(listener)对事件做出反应。事件发生后,浏览器监听到了这个事件,就会执行对应的监听函数。
绑定事件
给元素添加事件称为绑定事件 绑定事件有2种方式:传统绑定 和 监听绑定
传统方式
利用on开头的事件 如onclick
div.onclick = function(event){ console.log('触发事件') };
特点:绑定事件的唯一性,同一个元素同一个事件只能设置一个处理函数,最后绑定的处理函数将会覆盖前面注册的处理函数
div.onclick = function(event){ console.log('hi') };
div.onclick = function(event){ console.log('hello') };最后只输出hello
监听绑定
W3C标准推荐的绑定方式,通过addEventListener()绑定
IE9之前的IE不支持此方法,可使用attachEvent()代替
element.addEventListener('click',fn,bool)
如果bool不传或值为falsy 就让监听处理函数fn走冒泡,即当浏览器在冒泡阶段发现element有fn监听函数,就会调用fn,并提供事件信息。
如果bool为ture 就让监听处理函数fn走捕获,即当浏览器在捕获阶段发现element有fn监听函数,就会调用fn,并提供事件信息。
特点:同一个元素同一个事件可以绑定多个监听
div.addEventListener('click',function()=>{
alert('hi'); })
div.addEventListener('click',function()=>{
alert('hello'); })
//会先跳出hi接着跳出hello
事件的传播
事件(鼠标点击,鼠标经过等等事件)发生时会在元素节点之间按照特定的顺序传播 事件传播方式有分捕获和冒泡,根据事件在元素节点之间的传播顺序不同来区分 比如给一个div注册了点击事件:
捕获:网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到最具体的元素找监听函数的过程
冒泡:IE最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点找监听函数的过程。
<div class='爷爷'>
<div class='爸爸'>
<div class='儿子'>
文字
</div>
</div>
</div>
给三个div分别添加事件监听fnYe /fnBa /fnEr,点击文字,最先调用fnYe /fnBa /fnEr中的哪一个函数?
事件捕获:按爷爷=》爸爸=》儿子 的顺序看有没有函数监听
事件冒泡:按儿子=》爸爸=》爷爷 的顺序看有没有函数监听
术语
从外向内找监听函数,叫事件捕获
从内向外找监听函数,叫事件冒泡
事件委托
事件委托的原理:由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。
事件委托的具体操作:
场景一
要给100个按钮添加点击事件,咋办? 答:监听这100个按钮的祖先,等冒泡的时候判断target(e.target可返回触发事件的对象)是不是这100个按钮中的一个。
<div id=div1>
<span>span1</span>
<button>click 1</button>
<button>click 2</button>
...
<button>click 100</button>
</div>
<script>
div1.addEventListener('click',(e)=>{
const t = e.target
if(t.tagName.toLowerCase()==='button'){
console.log(button被点击了)
console.log('button内容是'+t.textContent)//可知道是第几个按钮被点击了
}
})
</script>
场景二
要监听目前不存在的元素的点击事件,咋办? 答:监听祖先,等点击的时候看看是不是我想要监听的元素即可。
setTimeout(()=>{
const button =document.createElement('button')
button.textContent = 'click 1'
div1.appendChild(button)
},1000)
div1.addEventListener('click',(e)=>{
const t = e.target
if(t.tagName.toLowerCase()==='button'){
console.log(button被点击了)
}
})