事件的传播
// 在当前案例中,点击了box2 的区域 相当于点击了 box1 内部的空间
// 在触发子元素的事件时,会将 行为 传播给父级的同类型事件
// 触发了子元素的点击事件时,会将该行为传播给父级
// 并 触发父级的同类型事件
// 在传递行为时,会将行为一直向上传递,如果父级有同类型事件,那么触发该事件
// 如果没有,则继续往上传递
// 阻止事件传播:stopPropagation
<div id="box1">
<div id="box2"></div>
</div>
var box1 = document.getElementById('box1')
var box2 = document.getElementById('box2')
var Body = document.body
box1.onclick = function (e) {
e.stopPropagation() //阻止事件传播(body不再传播)
console.log('点击了box1')
}
box2.onclick = function () {
console.log('点击了box2')
}
// box1.oncontextmenu = function () {
// console.log('右击了box1')
// }
Body.onclick = function () {
console.log('点击了body')
}
冒泡; 捕获; 目标
<div id="box1">
<div id="box2"></div>
</div>
<script>
// 冒泡:事件传播时,从目标开始传播,一直到父级,body...window
// 捕获:从最顶层开始,逐层向下传递,一直到目标
var box1 = document.getElementById('box1')
var box2 = document.getElementById('box2')
var Body = document.body
// 捕获的话 需要 传递 第三个参数 为 true
// addEventListener 第三个参数 默认值为 false 代表传播方式为冒泡
// 如果想改变传播方式为 捕获,那么需要 将第三个参数传递为true
box1.addEventListener('click' , function () {
console.log('点击了box1')
},true)
box2.addEventListener('click' , function () {
console.log('点击了box2')
},true)
Body.addEventListener('click' , function () {
console.log('点击了body')
},true)
</script>
事件委托
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var oUl = document.querySelector('ul')
var oLi = [...document.querySelectorAll('li')]
// 创建一个li节点
var newLi = document.createElement('li')
newLi.innerText = '我是JS创建的'
oUl.appendChild(newLi)
oUl.onclick = function (e) {
// console.log(e.target.nodeName)
if(e.target.nodeName === 'LI') {
console.log('点击了li')
}
}
/**
* 事件委托
* 因为事件冒泡的存在, 所以点击子元素时, 一定会触发给父级
*
* 所以可以将 子元素统一的事件, 都提交给 父级
*
* e.target: 触发事件的事件源
*
*
* 总结:
* 为什么要用事件委托
* 动态的添加了 li 时, 新加的li没有绑定上事件, 需要动态添加完成后重新绑定事件, 这样操作比较麻烦
* 所以此时可以利用 事件委托
*
* li 的点击事件必须委托给父级的 点击事件
*/
</script>
默认行为
<a href="xxx">xxxxxx</a>
<script>
var a = document.querySelector('a')
a.onclick = function (e) {
// 1. 方式1
// console.log('点击了 a 标签, 但是因为有 return false 所以默认的跳转功能被拦截')
// return false
// 2. 通过事件对象拦截 preventDefault() 拦截之后, 取消了 a标签的默认跳转功能
e.preventDefault()
}
</script>