DOM事件分为DOM事件模型与事件机制
DOM 事件模型
DOM事件模型分为捕获和冒泡。一个事件发生后,会在子元素和父元素之间传播,这种传播分为三个阶段。
- 捕获阶段:事件从window对象自上而下向目标节点传播
- 目标阶段:目标节点处理事件
- 冒泡阶段:事件从目标节点自下而上向window对象传播
事件机制
点击事件:进行事件监听,比如爷父子三代中包含文字,点击文字触发监听,都会触发
触发的调用顺序:网景为爷父子,IE为子父爷,有监听便调用,并提供事件信息
事件捕获:从外向内找监听函数 document.documentElement得HTML标签和document.body得body标签
事件冒泡:从内向外找监听函数
开发者自己选择放在捕获阶段还是冒泡阶段
事件委托
简述事件委托
关键:检查事件是否来自你所预期的元素。
优点:
可以大量节省内存占用,减少事件注册 可以实现当新增子对象时无需再次修改其绑定事件,对于动态内容部分尤为合适
代码实现
场景一:100个按钮,通过监听他的一个父元素即可
(监听100个元素的祖先,待冒泡时再判断target是否为这些按钮之一)
div1.addEventListener(
'click', (e) => {
const t = e.target
//标签的小写名称
if(t.tagName.toLowerCase() === 'button') {
console.log(t.innerText)
console.log(t.dataset.id)
}
})
先判断t.tagName是不是button
t.innerText是按钮内的内容,dataset.id是按钮的id
场景二:监听目前不存在的元素的点击事件
(监听祖先,待点击时看是否为要监听的元素)
先创造按钮,在按钮里加内容,将按钮加到div里,添加div的监听事件,并判断是否为button,t.tagName.toLowerCase() === 'button'
setTimeout(() => {
const button = document.createElement('button')
button.innerText = 'click 1'
div1.appendChild(button)
}, 1000)
div1.addEventListener('click', (e) => {
const t = e.target
if (t.tagName.toLowerCase() === 'button') {
console.log(t.innerText)
}
})
如何实现事件委托
我们来实现上例中父层元素 #list 下的 li 元素的事件委托到它的父层元素上
// 给父层元素绑定事件
document.getElementById('list').addEventListener('click', function (e) {
// 兼容性处理
var event = e || window.event;
var target = event.target || event.srcElement;
// 判断是否匹配目标元素
if (target.nodeName.toLocaleLowerCase === 'li') {
console.log('the content is: ', target.innerHTML);
}
});
封装事件委托
setTimeout(() => {
const button = document.createElement('button')
button.innerText = 'click 1'
div1.appendChild(button)
}, 1000)
function on(eventType,element,selector,fn){
if(!(element instanceof Element)){
element=document.querySelector(element)
}
element.addEventListener(eventType,(e)=>{
const t=e.target
if(t.matches(selector)){
fn(e)
}
})
}
on('click','#div1','button',()=>{
console.log('button被点击了')
})
知识点:
if(!(element instanceof Element)){
element=document.querySelector(element)
}
//匹配选择器
t.matches(selector)
事件委托:
给一个元素添加一个监听,看他的target是否满足Selector,满足就执行函数,否则就放过,其实这不是最完整的,还需要优化递归父亲
问:JS支持事件不?
不支持,这里的事件是DOM事件,是浏览器的功能,js只是调用了DOM提供的addEventListener这个API,那么如何手写JS事件…