JavaScript的事件传播
- 一、事件传播
- 1、事件传播的说明
- 2、阻止事件传播
- 二、目标冒泡捕获
- 1、冒泡
- 2、捕获
- 三、事件委托
- 1、事件委托的说明
- 2、为什么要用事件委托
- 四、阻止默认事件
- 1、方法一
- 2、方法二
一、事件传播
- 在触发子元素的事件时, 会将行为传播给父级的
同类型事件
- 触发了子元素的点击事件时, 会将该行为传播给父级, 并
触发父级的同类型事件
- 在传递行为时, 会将行为一直
向上传递
, 如果父级有同类型事件, 那么触发该事件; 如果没有, 则继续往上传递阻止事件传播: e.stopPropagation()
<div id="box1">
<div id="box2"></div>
</div>
<style>
#box1{
width: 200px;
height: 200px;
background-color: cadetblue;
}
#box2{
width: 100px;
height: 100px;
background-color: burlywood;
}
</style>
1、事件传播的说明
// 获取标签对象
var oBox1 = document.getElementById('box1');
var oBox2 = document.getElementById('box2');
var oBody = document.body;
oBox1.onclick = function () {
console.log('触发了box1的点击事件');
}
oBox2.onclick = function () {
console.log('触发了box2的点击事件');
}
oBox1.oncontextmenu = function () {
console.log('触发了box1的右键事件');
}
oBody.onclick = function () {
console.log('触发了body的点击事件');
}
2、阻止事件传播
// 获取标签对象
var oBox1 = document.getElementById('box1');
var oBox2 = document.getElementById('box2');
var oBody = document.body;
oBox1.onclick = function (e) {
// 阻止事件传播
e.stopPropagation()
console.log('触发了box1的点击事件');
}
oBox2.onclick = function () {
console.log('触发了box2的点击事件');
}
oBox1.oncontextmenu = function () {
console.log('触发了box1的右键事件');
}
oBody.onclick = function () {
console.log('触发了body的点击事件');
}
二、目标冒泡捕获
- 目标:
目标就是事件源
- 传播时,会从目标传播到
父级, body, html, document, window
<div id="box1">
<div id="box2"></div>
</div>
<style>
#box1{
width: 200px;
height: 200px;
background-color: cadetblue;
}
#box2{
width: 100px;
height: 100px;
background-color: burlywood;
}
</style>
1、冒泡
- 冒泡: 事件传播时, 从目标开始传播, 一直到到
父级, body...window
- window
默认
的传播方式为冒泡
// 获取标签对象
var oBox1 = document.getElementById('box1');
var oBox2 = document.getElementById('box2');
var oBody = document.body;
oBox1.onclick = function () {
console.log('触发了box1的点击事件');
}
oBox2.onclick = function () {
console.log('触发了box2的点击事件');
}
oBox1.oncontextmenu = function () {
console.log('触发了box1的右键事件');
}
oBody.onclick = function () {
console.log('触发了body的点击事件');
}
2、捕获
- 捕获:
从最顶层开始, 逐层向下传递, 一直到目标
// 获取标签对象
var oBox1 = document.getElementById('box1');
var oBox2 = document.getElementById('box2');
var oBody = document.body;
// 捕获
oBox1.addEventListener('click', function(){
console.log('触发了box1的点击事件');
}, true)
oBox2.addEventListener('click', function(){
console.log('触发了box2的点击事件');
}, true)
oBody.addEventListener('click', function(){
console.log('触发了body的点击事件');
}, true)
解释说明
- addEventListener第三个参数默认值为
false
,代表传播方式为冒泡
- 如果想改变传播方式为
捕获
, 那么需要将第三个参数传递为true
三、事件委托
- 因为事件
冒泡的存在
, 所以点击子元素时, 一定会触发给父级- 所以可以将子元素统一的事件, 都提交给
父级
e.target: 触发事件的事件源
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<style>
ul{
list-style: none;
}
li{
width: 200px;
height: 100px;
background-color: cornflowerblue;
margin-bottom: 5px;
}
</style>
1、事件委托的说明
// 获取标签对象
var oUl = document.querySelector('ul');
oUl.addEventListener('click', function(event){
console.log(event.target.nodeName);
})
// 获取标签对象
var oUl = document.querySelector('ul');
oUl.addEventListener('click', function(event){
// 判断
if(event.target.nodeName === 'LI'){
console.log('点击了li');
}
})
2、为什么要用事件委托
- 动态的添加了li时, 新加的li没有绑定上事件, 需要动态添加完成后重新绑定事件, 这样操作
比较麻烦
,所以此时可以利用事件委托
- li 的点击事件必须委托给
父级
的点击
事件
// 获取标签对象
var oUl = document.querySelector('ul');
var oLi = [...document.querySelectorAll('li')];
// 创建一个Li节点
var newLi = document.createElement('li');
newLi.innerText = '我是通过JS创建的';
oUl.appendChild(newLi);
// 此时页面只有3个li, 所以新插入的li没有点击事件
oLi.forEach(function (item, index) {
item.onclick = function () {
console.log(index + 1)
}
})
四、阻止默认事件
<!-- a标签默认是跳转页面 -->
<a href="xxx">点击跳转</a>
1、方法一
return false;
阻止a标签跳转
var oA = document.querySelector('a');
oA.onclick = function (e) {
return false
}
2、方法二
preventDefault();
拦截之后, 取消了a标签的默认跳转功能
var oA = document.querySelector('a');
oA.onclick = function (e) {
e.preventDefault()
}