javaScript在触发事件的时候存在特殊的事件传播机制(冒泡和排序)
1.冒泡(默认)
冒泡是指在触发一个事件后,JavaScript会向上寻找父元素是否存在与触发事件相同类型的事件,如果存在,JavaScript就会将该类事件触发,并且继续向上查找,直到body为止。从事件的目标的事件处理函数开始,依次向上,直到window的事件处理函数执行.
语法: dom.addEventListener('事件类型','事件处理函数'[,冒泡还是捕获]) 默认是false 冒泡
特点:
1)只会传播同类事件
2)只会从点击元素开始按html结构逐层向上,通通触发
3)内部元素不管有没有注册事件处理函数,只要上层元素有这个事件,上层的就会触发
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.outer {
width: 400px;
height: 400px;
background-color: brown;
margin: 50px auto;
position: relative;
}
.middle {
width: 300px;
height: 300px;
background-color: pink;
position: absolute;
top: 50px;
left: 50px;
}
.inner {
width: 200px;
height: 200px;
position: absolute;
top: 50px;
left: 50px;
background-color: gold;
}
</style>
<body>
<div class="outer">
<div class="middle">
<div class="inner">
</div>
</div>
</div>
<script>
// 事件的传播
// 思考一个问题
// 当大盒子嵌套小盒子的时候,并且两个盒子都有自己的点击事件
// 我点击了内部的盒子,外部的盒子的事件会不会触发
// 我们点击在金色的盒子上面的时候,也是点击在红色的盒子上
// 这是个既定事实,两个盒子的事件都被触发
// 这就是事件的传播
// inner => middle => outer => body => html => document => window
// 事件传播的注意
// 1 只会传播同类事件
// 2 只会从点击元素开始按html结构逐层向上,通通触发
// 3 内部元素不管内有注册事件处理函数,只要上层元素有这个事件,上层的就会触发
var outer = document.querySelector('.outer')
var inner = document.querySelector('.inner')
var middle = document.querySelector('.middle')
// 绑定事件
outer.addEventListener('click', function () {
console.log('outer click')
})
inner.addEventListener('click', function () {
console.log('inner click')
})
middle.addEventListener('click', function () {
console.log('middle click')
})
document.onclick = function () {
console.log('document click')
}
window.onclick = function () {
console.log('window click')
}
document.body.onclick = function () {
console.log('body click')
}
</script>
</body>
</html>
2.捕获
捕获与冒泡相反,捕获是从上到下,从window到目标事件,存在同类型的事件就会自动触发,从window的事件处理函数函数开始,依次向下,直到事件目标的事件处理函数执行.
语法: 元素.addEventListener('事件类型','事件处理函数',true) 默认false 冒泡 true为捕获
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.outer {
width: 400px;
height: 400px;
background-color: brown;
margin: 50px auto;
position: relative;
}
.middle {
width: 300px;
height: 300px;
background-color: pink;
position: absolute;
top: 50px;
left: 50px;
}
.inner {
width: 200px;
height: 200px;
position: absolute;
top: 50px;
left: 50px;
background-color: gold;
}
</style>
<body>
<div class="outer">
<div class="middle">
<div class="inner">
</div>
</div>
</div>
<script>
// 事件的目标
// 事件对象.target (兼容写法 事件对象.srcElement)
// 事件捕获
// 从window的事件处理函数函数开始,依次向下,直到事件目标的事件处理函数执行
// 也就是从上往下
// 元素.addEventListener('事件类型','事件处理函数',是否捕获true)
var outer = document.querySelector('.outer')
var inner = document.querySelector('.inner')
var middle = document.querySelector('.middle')
// 绑定事件
outer.addEventListener('click', function (e) {
console.log('本次点击的事件目标')
console.log(e.target)
console.log('outer click')
}, true)
inner.addEventListener('click', function (e) {
console.log('本次点击的事件目标')
console.log(e.target)
console.log('inner click')
}, true)
middle.addEventListener('click', function (e) {
console.log('本次点击的事件目标')
console.log(e.target)
console.log('middle click')
}, true)
</script>
</body>
</html>
3. e.stopPropagation()阻止事件传播
在JavaScript事件对象中有可以阻止事件传播机制的方法,就是stopPropagation,在事件中调用 e.stopPropagation()就可以将事件传播中断。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.outer {
width: 400px;
height: 400px;
background-color: brown;
margin: 50px auto;
position: relative;
}
.middle {
width: 300px;
height: 300px;
background-color: pink;
position: absolute;
top: 50px;
left: 50px;
}
.inner {
width: 200px;
height: 200px;
position: absolute;
top: 50px;
left: 50px;
background-color: gold;
}
</style>
<body>
<div class="outer">
<div class="middle">
<div class="inner">
</div>
</div>
</div>
<script>
// 阻止事件的传播
// 语法:事件对象.stopPropagetion()
// 兼容写法 事件对象.cancelBubble = true ie678只能用这个
// 阻止事件传播,并不暂停自己事件处理函数的代码,只是不再进行事件传播机制
var outer = document.querySelector('.oute r')
var inner = document.querySelector('.inner')
var middle = document.querySelector('.middle')
// 绑定事件
outer.addEventListener('click', function (e) {
e.stopPropagation()
console.log('本次点击的事件目标')
console.log(e.target)
console.log('outer click')
}, false)
middle.addEventListener('click', function (e) {
e.stopPropagation()
console.log('本次点击的事件目标')
console.log(e.target)
console.log('middle click')
}, false)
inner.addEventListener('click', function (e) {
console.log('本次点击的事件目标')
console.log(e.target)
console.log('inner click')
}, false)
</script>
</body>
</html>