事件绑定有两类,普通绑定和事件代理。通用事件绑定即适用于普通绑定又适用于事件代理。即封装普通绑定和事件代理。
事件代理:业务场景适用于类似瀑布流、上拉加载批量绑定事件,基于事件冒泡机制,在其父元素绑定事件,减少批量绑定对于内存的消耗
如有疏漏,欢迎指正。
示例:给a标签绑定点击事件,打印标签文本内容,同时点击按钮插入a标签。
HTML
<div id="box">
<a id="a1" href='#'>a1</a>
<a id="a2" href='#'>a2</a>
<a id="a3" href='#'>a3</a>
<a id="a4" href='#'>a4</a>
<a id="a5" href='#'>a5</a>
<a id="a6" href='#'>a6</a>
<button type="button" id='addA'>增加a标签</button>
</div>
JavaScript
function bindEvent(elem,type,fn){//元素、事件类型、调用函数
elem.addEventListener(type,fn)
}
const addA=document.getElementById('addA')
//普通绑定
bindEvent(addA,'click',event=>{
const aLength=box.childElementCount;
const creatA=document.createElement('a')
creatA.innerHTML='我是点击增加的a'+aLength
box.appendChild(creatA)
})
//事件代理
const box=document.getElementById('box')
bindEvent(box,'click',event=>{
event.prevntDefault()
const target=event.targe
if target==='A'){//判断目标元素为A时,打印内容
alert('target.innerHTML')
}
})
思考,如何封装bindEvent,同时判断目标元素?
function bindEvent(elem,type,selector,fn){//元素、事件类型、选择器、调用函数。
if(fn=null){//如果调整参数:选择器和函数顺序,可以不用判断
fn=selector
selector=null
}
elem.addEventListener(type,event=>{
const target=event.target
if(selector){
//事件代理
if(target.metches(selector)){
fn.call(target,event)
}
}else{
//普通绑定
fn.call(target,event)
}
})
}
bindEvent(box,'click','a',function(event){
console.log(this.innerHTML)//改用Es5,因为箭头函数this是指向父作用域
})
bindEvent(addA,'click',event=>{
const aLength=box.childElementCount;
const creatA=document.createElement('a')
creatA.innerHTML='我是点击增加的a'+aLength
box.appendChild(creatA)
})