1. 事件传播
<div id="box1">
<div id="box2"></div>
</div>
在当前案例中, 点击了 box2 的区域 相当于点击了 box1 内部的空间
在触发子元素的事件时, 会将行为传播给父级的同类型事件
触发了子元素的点击事件时, 会将该行为传播给父级,并触发父级的同类型事件
在传递行为时, 会将行为一直向上传递, 如果父级有同类型事件, 那么触发该事件,如果没有,就一直向上传递
阻止事件传播
语法:e.stopPropagation()
本级不阻止,阻止向上一级传播事件
<script>
box1.onclick = function (e) {
e.stopPropagation()
console.log('触发了 box1 的点击事件')
}
box2.onclick = function () {
console.log('触发了 box22222 的点击事件')
}
box1.oncontextmenu = function () {
console.log('触发了 box1111111 的右键事件')
}
myBody.onclick = function () {
console.log('触发了 body 的点击事件')
}
</script>
2. 目标冒泡捕获
window的默认传播方式是冒泡
传播时 会从目标传播到父级, body, html, document, window
冒泡: 事件传播时, 从目标开始传播, 一直到到父级, body...window
捕获: 从最顶层开始, 逐层向下传递, 一直到 目标
如果要改为捕获的话这里要用到addEventListener的第三个参数 默认第三个
参数是false 代表的传播方式是冒泡
如果我们想要改变传播方式为捕获,只需要改变第三个参数为true 即可
3. 事件委托
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
获取元素ul
var myUl = document.querySelector('ul')
获取元素li 这里获取的是伪数组所以要展开就是...
var myLi = [...document.querySelectorAll('li')]
对第一个li添加点击事件
myLi[0].onclick = function () {
console.log('111111111111')
}
对第二个li添加点击事件
myLi[1].onclick = function () {
console.log('222222222222222')
}
对第三个li添加点击事件
myLi[2].onclick = function () {
console.log('33333333333333')
}
此时页面还没有 第4个li, 所以此处不能这样使用
myLi[3].onclick = function () {
console.log('33333333333333')
}
此时页面只有 3 个 li, 所以新插入的li没有点击事件
myLi.forEach(function (item, index) {
item.onclick = function () {
console.log(index + 1)
}
})
myUl.onclick = function (e) {
console.log(e.target, '触发了 ul 的点击事件')
if (e.target.nodeName === 'LI') {
console.log('点击了 li')
}
}
创建一个 Li 节点
var newLi = document.createElement('li')
newLi.innerText = '我是通过 JS 创建的'
myUl.appendChild(newLi)
事件委托
因为事件冒泡的存在, 所以点击子元素时, 一定会触发给父级
所以可以将 子元素统一的事件, 都提交给 父级
e.target: 触发事件的事件源
总结:
为什么要用事件委托?
动态的添加了 li 时, 新加的li没有绑定上事件, 需要动态添加完成后重新绑定事
件, 这样操作比较麻烦所以此时可以利用 事件委托
注:li 的点击事件必须委托给父级的 点击事件
4.阻止默认事件
<a href="xxx">11111111</a>
<script>
var a = document.querySelector('a')
a.onclick = function (e)
{
return false
1. 方式1
console.log('点击了 a 标签, 但是因为有 return false 所以默认的
跳转功能被拦截')
2. 通过事件对象拦截 preventDefault() 拦截之后, 取消了
a标签的默认跳转功能
e.preventDefault()
}
</script>