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