1.事件对象
- 事件对象是什么
- 也是个对象,这个对象里有事件触发时的相关信息
- 例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息
- 如何获取
- 在事件绑定的回调函数的第一个参数就是事件对象
- 一般命名为event、ev、e
元素. addEventListener('click', function (e) {
}
事件对象属性
部分常用属性
- type
- 获取当前的事件类型
- clientX/ clientY
- 获取光标相对于浏览器可见窗口左上角的位置
- offsetX/offsetY
- 获取光标相对于当前DOM元素左上角的位置
- key
- 用户按下的键盘键的值
- 现在不提倡使用keyCode
<body>
<button>点击</button>
<script>
//鼠标移动事件
document.addEventListener('click', function(e) {
console.log('clientX:' + e.clientX, 'clientY:' + e.clientY);
console.log('pageX:' + e.clientX, 'pageY:' + e.clientY);
console.log('offsetX:' + e.clientX, 'offsetY:' + e.clientY);
})
</script>
</body>
2.事件流
2.1事件流和两个阶段说明
2.2事件捕获和事件冒泡
-
事件冒泡概念:
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这-过程被称为事件冒泡 -
简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件
-
事件冒泡是默认存在的
-
事件捕获概念:
-
从DOM的根元素开始去执行对应的事件(从外到里)
-
事件捕获需要写对应代码才能看到效果
-
代码:
DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制)
说明:
- addEventListener第三个参数传入true代表是捕获阶段触发(很少使用)
- 若传入false代表冒泡阶段触发,默认就是false
- 若是用L0事件监听,则只有冒泡阶段,没有捕获
<!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>
.father {
margin: 100px auto;
width: 500px;
height: 500px;
background-color: pink;
}
.son {
width: 200px;
height: 200px;
background-color: purple;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
let fa = document.querySelector('.father')
let son = document.querySelector('.son')
fa.addEventListener('click', function () {
alert('我是爸爸')
}, true)
son.addEventListener('click', function () {
alert('我是儿子')
}, true)
document.addEventListener('click', function () {
alert('我是爷爷')
}, true)
// btn.onclick = function() {}
</script>
</body>
</html>
2.3阻止事件流动
2.3.1
- 因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素
- 若想把事件就限制在当前元素内,就需要阻止事件流动
- 阻止事件流动需要拿到事件对象
- 语法:
事件对象.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>
<style>
.father {
margin: 100px auto;
width: 500px;
height: 500px;
background-color: pink;
}
.son {
width: 200px;
height: 200px;
background-color: purple;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
let fa = document.querySelector('.father')
let son = document.querySelector('.son')
fa.addEventListener('click', function (e) {
alert('我是爸爸')
e.stopPropagation()
})
son.addEventListener('click', function (e) {
alert('我是儿子')
//阻止流动
e.stopPropagation()
})
document.addEventListener('click', function () {
alert('我是爷爷')
})
// btn.onclick = function() {}
</script>
</body>
</html>
2.3.2
鼠标经过事件:
- mouseover 和mouseout会有冒泡效果
- mouseenter和mouseleave没有冒泡效果(推荐)
<!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>
.father {
margin: 100px auto;
width: 500px;
height: 500px;
background-color: pink;
}
.son {
width: 200px;
height: 200px;
background-color: purple;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
let fa = document.querySelector('.father')
let son = document.querySelector('.son')
fa.addEventListener('mouseenter', function (e) {
console.log(111)
})
</script>
</body>
</html>
2.3.3
阻止默认行为,比如链接点击不跳转,表单域的跳转
语法:
e. preventDefault()
<body>
<a href="http://www.baidu.com">跳转到百度</a>
<script>
let a = document.querySelector('a')
a.addEventListener('click', function (e) {
// 阻止默认行为 方法
e.preventDefault()
})
</script>
</body>
2.4两种注册事件的区别
2.4.1传统on注册(L0)
- 同一个对象,后面注册的事件会覆盖前面注册(同一个事件)
- 直接使用null覆盖就可以实现事件的解绑
- 都是冒泡阶段执行的
<body>
<button>点击</button>
<script>
let btn = document.querySelector('button')
//多次相同的事件,只执行最后一次
btn.onclick = function() {
alert(1)
}
btn.onclick = function() {
alert(2)
}
// 解绑事件
btn.onclick = null
</script>
</body>
2.4.2事件监听注册(L2)
-
语法: addventListener(事件类型,事件处理函数,是否使用捕获)
-
后面注册的事件不会覆盖前面注册的事件(同一个事件)
-
可以通过第三个参数去确定是在冒泡或者捕获阶段执行
-
必须使用removeEventListener(事件类型,事件处理函数,获取捕获或者冒泡阶段)
-
匿名函数无法被解绑
<body> <button>点击</button> <script> let btn = document.querySelector('button') btn.addEventListener('click', function () { alert(1) }) btn.addEventListener('click', function () { alert(2) }) // 解绑事件 // 匿名函数无法被解绑 所以需要定义有名函数 function add () { alert(23) } btn.addEventListener('click', add) btn.removeEventListener("click", add) </script> </body>
3.事件委托
目标:能够说出事件委托的好处
- 事件委托是利用事件流的特征解决一些开 发需求的知识技巧
- 总结:
- 优点:给父级元素加事件(可以提高性能)
- 原理:事件委托其实是利用事件冒泡的特点,给父元素添加事件,子元素可以触发
- 实现:事件对象.target可以获得真正触发事件的元素
<body>
<ul>
<li>我是1个小li</li>
<li>我是2个小li</li>
<li>我是3个小li</li>
<li>我是4个小li</li>
<li>我是5个小li</li>
</ul>
<script>
// 不要每个小li注册事件了 而是把事件委托给他的父级
// 事件委托是给父级添加事件 而不是孩子添加事件
let ul = document.querySelector('ul')
ul.addEventListener('click', function(e) {
// alert('我点击了')
// 得到当前的元素
console.log(e.target)
e.target.style.color = 'red'
})
</script>
</body>