注册事件
事件监听
addEventListener()事件监听(IE9以后支持)默认冒泡 事件类型不以on开头
Ele.addEventListener(‘事件类型’,functionName[,是否冒泡])
attacheEvent()事件监听(IE678支持)
Ele.attacheEvent(‘on事件类型’, functionName);
兼容
删除事件
传统方式
Ele.on事件类型 = null
监听方式
Ele.removeEventListener(‘事件类型’,functionName[,冒泡或捕获]) //false代表冒泡,true代表捕获
Ele.detachEvent(‘on事件类型’, functionName);
兼容
事件流
事件流描述的是从页面中接收事件的顺序
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即Dom事件流
事件冒泡
点击按钮
先触发按钮点击事件,再触发盒子的点击事件
addEventListener()事件监听默认以冒泡的形式触发事件
事件捕获
点击按钮
先触发盒子的点击事件,再触发按钮点击事件
一个完整事件流都要经历三个阶段
1.捕获阶段
2.当前目标阶段
3.冒泡阶段
HTML级(默认冒泡)
点击span
span->div->body
点击body
只触发body对应事件
Dom0级(默认冒泡)
点击span
span->div->body
点击body
只触发body对应事件
Dom2级(默认冒泡)
点击span
span->div->body
点击body
只触发body对应事件
Dom2级 捕获
点击span
body->div->span
点击body
只触发body对应事件
事件冒泡与事件捕获执行顺序(技术蛋老师视频:https://www.bilibili.com/video/BV1m7411L7YW/?spm_id_from=333.999.0.0&vd_source=859573b09f48050d76eb5bf373891405)
<!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>
<style>
*{
margin: 0;
height: 0;
}
div{
padding: 50px 30px;
margin-top: 50px;
padding-top: 0;
text-align: center;
height: auto;
}
.grandma{
margin: 50px auto;
width: 50%;
background-color: aqua;
}
.mother{
background-color: greenyellow;
}
.daughter{
background-color: orange;
}
.baby{
background-color: red;
height: 200px;
}
</style>
</head>
<body>
<div class="grandma">
grandma
<div class="mother">
mother
<div class="daughter">
daughter
<div class="baby">baby</div>
</div>
<!--
<div class="daughter" onclick="alert('点击了daughter,行内事件触发')">
daughter 设置了行内事件
<div class="baby">baby</div>
</div>
-->
</div>
</div>
<script>
var grandma = document.getElementsByClassName('grandma')[0]
var mother = document.getElementsByClassName('mother')[0]
var daughter = document.getElementsByClassName('daughter')[0]
var baby = document.getElementsByClassName('baby')[0]
function clickFn(){alert('点击了'+this.className)}
baby.addEventListener('click',clickFn,false) //冒泡
daughter.addEventListener('click',clickFn,true) //捕获
mother.addEventListener('click',clickFn,true) //捕获
grandma.onclick = clickFn //冒泡
// mother->daughter->baby->grandma
</script>
</body>
</html>
点击baby
mother->daughter->baby->grandma
点击daughter
mother->daughter->grandma
点击grandma
grandma
点击baby
mother->daughter->baby->daughter行内事件->grandma
点击daughter
mother->daughter->daughter行内事件->grandma
点击mother
mother->grandma
阻止事件冒泡
Ele.addEventListener(‘事件类型’,function(e){
e.stopPropagation() //stopPropagation()方法在e的原型链上
})
参数e(事件对象)的属性方法
e.target 和 this 的区别
this 是事件绑定的元素(绑定这个事件处理函数的元素) 。
e.target 是事件触发的元素。(点击的那个Dom对象)
通常情况下terget 和 this是一致的, 但有一种情况不同,那就是在事件冒泡时(父子元素有相同事件,单击子元素,父元素的事件处理函>数也会被触发执行), 这时候this指向的是父元素,因为它是绑定事件的元素对象, 而target指向的是子元素,因为他是触发事件的那个具体元素对象。
<div>123</div>
<script>
var div = document.querySelector('div');
div.addEventListener('click', function(e) {
// e.target 和 this指向的都是div
console.log(e.target);
console.log(this);
});
</script>
<ul>
<li>abc</li>
<li>abc</li>
<li>abc</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
// 我们给ul 绑定了事件 那么this 就指向ul
console.log(this); // ul
// e.target 触发了事件的对象 我们点击的是li e.target 指向的就是li
console.log(e.target); // li
});
</script>
阻止默认行为
方法一
<a href="javascript:;"></a>
方法二
<a href="#"></a>
方法三
a.onclick=function(e){
e.preventDefault()
}
事件委托
利用冒泡的特性,把多个相同子元素的相同效果由父元素执行
<ul>
<li>点我弹出1</li>
<li>点我弹出2</li>
<li>点我弹出3</li>
<li>点我弹出4</li>
<li>点我弹出5</li>
<li>点我弹出6</li>
<li>点我弹出7</li>
<li>点我弹出8</li>
</ul>
<script>
let ul=document.querySelector('ul')
ul.addEventListener('click',function(e){
alert(e.target.innerText)
})
//也可以使用on事件
ul.onclick=function(e){
alert(e.target.innerText)
}
</script>