DOM事件绑定的几种方式javascript
事件流html
事件委托java
target 与 currentTarget的区别是什么?node
<button onclick="btnClick1()" onclick="btnClick2()">click me</button>
<script> function btnClick1(){console.log('click!1')} function btnClick2(){console.log('click!2')} </script>
复制代码
若是绑定了同一元素绑定了多个onclick 事件,那么只会执行第一个。jquery
btn.onclick = function(){console.log('1')}
btn.onclick = function(){console.log('2')}
复制代码
若是是在js里面匿名绑定的,那么只会执行最后一个。chrome
btn.attachEvent('onclick', function(){})
复制代码
1.事件名,带有onui
2.若是同一元素绑定了多个click 事件,都会执行,而且有前后顺序。spa
3.注意:这个方法,chrome不支持,只有IE支持code
4.绑定了事件记得取消绑定,避免内存泄漏cdn
btn.addEventListener('click',function(){}, false) // 能够区分捕获阶段 和 冒泡阶段
复制代码
1.事件名不带on
2.若是绑定了同一元素绑定了多个click 事件,都会执行,而且有前后顺序。
3.而且第三个参数的意思是是否开启/使用事件捕获阶段,默认是false,就是默认是冒泡阶段。
4.绑定了事件记得取消绑定,避免内存泄漏
if (a.addEventListener) {
a.addEventListener('click', function(){
console.log('is addEventListener!')
})
} else if (a.attachEvent) {
a.attachEvent('onclick', function(){
console.log('is attachEvent!')
})
} else {
console.log('others')
}
复制代码
1.捕获阶段:从上往下,document会先捕获到,到html,body,...,直到触发事件的那个元素
2.目标阶段:触发事件的那个元素
3.冒泡阶段:从下往上,触发事件的那个元素往父元素,...,到body,html,document
其实刚开始DOM0的时候是只有目标阶段 和 冒泡阶段的,直到出现了DOM2,才引进了捕获阶段。
DOM0事件流只有两个阶段:目标阶段 + 冒泡阶段
btn.onclick = function(){
}
复制代码
DOM2事件流只有3个阶段:捕获阶段 + 目标阶段 + 冒泡阶段
addEventListener 第二个参数的意思是,是否开启事件捕获。能够区分,true 事件捕获,默认是false 事件冒泡。
btn.addEventListener('click',function(){
}, true) // true 事件捕获
btn.removeEvenetListener('click',function(){
}, false) // false 事件冒泡(默认)
复制代码
事件委托是,把本身元素的响应事件委托到其余元素上面。通常是委托再父元素上。
1.减小内存的消耗
若是是一个列表,咱们给每一个列表项都绑定一样的事件,是很是消耗内存的。
咱们能够绑定到父组件列表上面,这样能够减小内存的消耗;
2.减小重复工做
咱们的列表项,若是删除增长,都要重复进行一个操做就是删除事件和绑定事件。
若是咱们绑定在父组件上面,咱们就能够不用作这些重复的工做了。
on/delegate
事件委托通常是由 事件冒泡来实现的
案例🌰:使用addEventListener点击li弹出内容,而且动态添加li以后有效
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
复制代码
// 给父层元素绑定事件
document.getElementById('list').addEventListener('click', function (e) {
var target = event.target
if (target.nodeName.toLocaleLowerCase === 'li') {
console.log('the content is: ', target.innerHTML);
}
});
复制代码
target指的是目标阶段。
currentTarget指的是捕获阶段,目标阶段 和 冒泡阶段。(通常指目标元素的父级)
<div id="c">c
<div id="b">b
<div id="a">a</div>
</div>
</div>
复制代码
const b = document.getElementById('b');
const a = document.getElementById('a');
const c = document.getElementById('c');
b.addEventListener('click', (e)=>{
console.log("click b=>", "target:",e.target, "currentTarget:",e.currentTarget)
})
//b.addEventListener('click', (e)=>{
// console.log("click b=>", "target:",e.target, "currentTarget:",e.currentTarget)
//},true) //捕获阶段
a.addEventListener('click',(e)=>{
console.log("click a=>", "target:",e.target, "currentTarget:",e.currentTarget)
})
//a.addEventListener('click',(e)=>{
// console.log("click a=>", "target:",e.target, "currentTarget:",e.currentTarget)
//},true) //捕获阶段
c.addEventListener('click',(e)=>{
console.log("click c=>", "target:",e.target, "currentTarget:",e.currentTarget)
})
//c.addEventListener('click',(e)=>{
// console.log("click c=>", "target:",e.target, "currentTarget:",e.currentTarget)
//},true)//捕获阶段
复制代码
捕获阶段:c(currentTarget)
目标阶段:c (target)
冒泡阶段:c(currentTarget)
捕获阶段:c
通过c模块,触发了c模块的click事件,因此c模块的currentTarget是c模块,可是target仍是b模块
目标阶段:b
对于b模块本身来讲,target 和 currentTarget都是本身
冒泡阶段:c
通过c模块,触发了c模块的click事件,因此c模块的currentTarget是c模块,可是target仍是b模块
点击b模块.jpg
捕获阶段:c -- b
通过了c模块和b模块,因此触发了c,b模块的点击事件。对于c模块来讲,currentTarget就是c模块,target仍是a模块。对于b模块来讲,currentTarget就是b模块,target仍是a模块。
目标阶段:a
对于a模块本身来讲,target 和 currentTarget都是本身
冒泡阶段:b --- c
通过了c模块和b模块,因此触发了c,b模块的点击事件。对于c模块来讲,currentTarget就是c模块,target仍是a模块。对于b模块来讲,currentTarget就是b模块,target仍是a模块。