题目
编写一个通用的事件监听函数
function bindEvent(elem,type,selector,fn) {
if (fn == null) {
fn = selector
selector = null
}
elem.addEventLister(type,event=>{
const target = event.target
if (selector) {
if(target.matches(selector)){
fn.call(target,event)
}
}else{
fn.call(target,event)
}
})
}
描述事件冒泡的流程
无线下拉的图片列表,如何监听每个图片的点击?
- 事件代理
- 用e.target获取触发元素
- 用matches来判断是否触发元素
- 代码参考问题一
知识点
事件绑定
<button id="btn1">一个按钮</button>
var btn = document.getElementById('btn1')
btn.addEventListener('click', event => {
console.log('clicked')
})
事件冒泡
- 事件被触发后基于DOM结构向上逐级触发的行为,可以通过event.target获取到最初触发的元素
- stopPropagation阻止事件冒泡
- 事件冒泡顺序与DOM树结构有关
代码示例:点击激活按钮激活,点击其他按钮取消
<body>
<div id="div1">
<p id='p1'>激活</p>
<p id='p1'>取消</p>
<p id='p1'>取消</p>
<p id='p1'>取消</p>
</div>
<div id='div2'>
<p id='p5'>取消</p>
<p id='p6'>取消</p>
</div>
</body>
function bindEvent(elem,type, fn) {
elem,addEventListener(type,fn)
}
var p1 = document.getElementById('p1')
var body = document.body
bindEvent(p1, 'click', event => {
event.stopPropagation()
alert('激活')
})
bindEvent(body,'click', event => {
alert('取消')
const target = event.target
})
事件代理
- 通过绑定上一级的标签,结合冒泡实现对标签下所有事件的响应。代码简洁,减少浏览器内存占用。
- 不要滥用,一般用在下级DOM较多比较复杂的如瀑布流这一类的不好绑定事件的DOM的应用
<div id="div3">
<a href="#">a1</a><br>
<a href="#">a2</a><br>
<a href="#">a3</a><br>
<a href="#">a4</a><br>
<button>加载更多...</button>
</div>
function bindEvent(elem,type, fn) {
elem,addEventListener(type,fn)
}
const div3 = document.getElementById('div3')
bindEvent(div3, 'click', event => {
event.preventDefault()
alert(this.innerHTML)
if(target.nodeName === 'A'){
alert(target.innerHTML)
}
})