事件传播
在当前案例中, 点击了box2的区域相当于点击了box1内部的空间
在触发子元素的事件时, 会将 行为 传播给父级的同类型事件
触发了子元素的点击事件时, 会将该行为传播给父级,
并 触发父级的同类型事件
在传递行为时, 会将行为一直向上传递, 如果父级有同类型事件, 那么触发该事件
如果没有, 则继续往上传递
阻止事件传播: e.stopPropagation()
<style>
width: 500px
height: 500px
background-color: pink
}
width: 200px
height: 200px
background-color: green
}
</style>
<div id="box1">
<div id="box2"></div>
</div>
var box1 = document.getElementById('box1')
var box2 = document.getElementById('box2')
var myBody = document.body
box1.onclick = function (e) {
e.stopPropagation() // 阻止事件传播
console.log('触发了 box1 的点击事件')
}
box2.onclick = function () {
console.log('触发了 box2的点击事件')
}
myBody.onclick = function () {
console.log('触发了 body 的点击事件')
}
目标冒泡捕获
目标: 目标就是事件源
传播时会从目标传播到父级,body,html,document,window
window默认的传播方式为冒泡
冒泡: 事件传播时, 从目标开始传播, 一直到到父级,body...window
捕获: 从最顶层开始, 逐层向下传递, 一直到目标
捕获的话需要传递第三个参数为,true
addEventListener 第三个参数 默认值 为 false 代表传播方式 为 冒泡
如果想改变传播方式为 捕获, 那么需要 将第三个参数传递为 true
box1.addEventListener('click', function () {
console.log('触发了 box1 的点击事件')
}, true)
box2.addEventListener('click', function () {
console.log('触发了 box2 的点击事件')
}, true)
myBody.addEventListener('click', function () {
console.log('触发了 body 的点击事件')
}, true)
事件委托
因为事件冒泡的存在, 所以点击子元素时, 一定会触发给父级
所以可以将 子元素统一的事件, 都提交给 父级
e.target: 触发事件的事件源
总结:
为什么要用事件委托
动态的添加了 li 时, 新加的li没有绑定上事件, 需要动态添加完成后重新绑定事件, 这样操作比较麻烦
所以此时可以利用 事件委托
li 的点击事件必须委托给父级的 点击事件
阻止默认事件
<a href="#">11111111</a>
<script>
var a = document.querySelector('a')
a.onclick = function (e) {
e.preventDefault()
}
</script>
开关案例
<button>点击获取验证码</button>
<script>
var btn = document.querySelector('button')
var flag = true
btn.onclick = function () {
if (!flag) return
var count = 5
btn.innerText = `${count} S后可以重新点击`
flag = false
var timer = setInterval(function () {
count--
btn.innerText = `${count} S后可以重新点击`
if (count == 0) {
flag = true
btn.innerText = `点击获取验证码`
clearInterval(timer)
}
}, 1000)
}
</script>