1. 注册事件
给元素添加事件,称为注册事件或者绑定事件
// 方法1:给DOM元素的属性赋值
// 特点:同一个元素,同一个事件,只能设置一个处理函数
// 最后注册的处理函数将会覆盖前面的处理函数
<button>按钮</button>
let btn = document.querySelector('button')
btn.onclick = function() {
console.log('我被点击了')
}
//方法2:调用DOM的addEventListener()方法
// 特点:同一个元素,同一个事件可以注册多个监听器,按注册顺序依次执行
<button>按钮</button>
let btn = document.querySelector('button')
btn.addEventListener('click', function() {
console.log('我被点击了')
})
2. 事件监听函数
- target.addEventListener(type, listener, options)
- type: 事件类型
- listener: 事件处理方法
- options: 传递一个对象,可选,默认全是false
- capture: 是否捕获阶段监听
- once: 是否只监听一次
- passive: 是否忽略preventDefault
- target.addEventListener(type, listener, useCapture)
- useCapture: 可选,true表示在捕获阶段调用listener,false表示冒泡阶段
- target.removeEventListener
- target.removeEventListener(‘click’, handler)
- target.removeEventListener(‘click’, handler, true) ```javascript function isClick() { console.log(‘我被点击了’) }
let btn = document.querySelector(‘button’) btn.addEventListener(‘click’, isClick)
btn.removeEventListener(‘click’, isClick) // 取消事件监听
**
<a name="RPgTA"></a>
# 3. DOM事件流
**HTML中的标签都是互相嵌套的,我们可以将元素想象成一个盒子装一个盒子,document是最外面的大盒子。当你单击一个div时,同时你也单击了div的父元素,甚至整个页面。那么是先执行父元素的单击事件,还是先执行div的单击事件?**<br />**
- 事件流描述的是从页面中接收事件的顺序
- 事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流
**DOM 事件流会经历3个阶段:**
1. 捕获阶段
2. 当前目标阶段
3. 冒泡阶段
我们向水里面扔一块石头,首先它会有一个下降的过程,这个过程就可以理解为从最顶层向事件发生的最具体元素(目标点)的捕获过程;之后会产生泡泡,会在最低点( 具体元素)之后漂浮到水面上,这个过程相当于事件冒泡。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2205407/1611320102963-5a82b5ba-2cca-46d2-82fa-e47b1ecdb22c.png#align=left&display=inline&height=254&margin=%5Bobject%20Object%5D&name=image.png&originHeight=254&originWidth=689&size=29319&status=done&style=none&width=689)
```html
<div class="parent">parent
<div class="child">child
<div class="target">target</div>
</div>
</div>
<style>
div {
border: 1px solid;
margin: 10px;
}
</style>
<script>
const $ = s => document.querySelector(s)
$('.parent').addEventListener('click', function () {
console.log('在捕获阶段,parent 开始处理')
}, true)
$('.child').addEventListener('click', function () {
console.log('在捕获阶段,child 开始处理')
// e.stopPropagation()
}, true)
$('.target').addEventListener('click', function () {
console.log('在捕获阶段,target 开始处理')
}, true)
$('.parent').addEventListener('click', function () {
console.log('在冒泡阶段,parent 开始处理')
}, false)
$('.child').addEventListener('click', function (e) {
console.log('在冒泡阶段,child 开始处理')
}, false)
$('.target').addEventListener('click', function (e) {
console.log('在冒泡阶段,target 开始处理')
}, false)
</script>
4. 事件对象**
事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象**。**
例如:
- 谁绑定了这个事件。
- 鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置。
- 键盘触发事件的话,会得到键盘的相关信息,如按了哪个键。**
事件触发发生时就会产生事件对象,并且系统会以实参的形式传给事件处理函数。
所以,在事件处理函数中声明1个形参用来接收事件对象。
事件对象的属性和方法**
- e.target 返回触发事件的对象
- e.type 返回事件的类型(click,mouseover等)
- e.preventDefault() 该方法阻止默认事件(不让链接跳转等)
- e.stopPropagation() 阻止冒泡
**
e.target 和 this 的区别
- this 是事件绑定的元素(绑定这个事件处理函数的元素)
- e.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>
5. 阻止默认行为
html中一些标签有默认行为,例如a标签被单击后,默认会进行页面跳转
target.preventDefault()可以阻止默认行为
<a href="https://www.baidu.com">百度</a>
<script>
// 阻止默认行为 让链接不跳转
var a = document.querySelector('a')
a.addEventListener('click', function(e) {
e.preventDefault()
})
</script>
6. 阻止事件冒泡
target.stopPropagation()可以阻止事件冒泡
<div class="father">father父亲
<div class="son">son儿子</div>
</div>
<script>
let son = document.querySelector('.son')
// 给son注册单击事件
son.addEventListener('click', function(e) {
console.log('son')
e.stopPropagation() // stop 停止 Propagation 传播
}, false)
let father = document.querySelector('.father')
// 给father注册单击事件
father.addEventListener('click', function() {
console.log('father')
}, false)
// 给document注册单击事件
document.addEventListener('click', function() {
console.log('document')
})
</script>
7. 事件委托
事件委托:
不给子元素注册事件
给父元素注册事件
把处理代码在父元素的事件中执行
事件委托的原理:
给父元素注册事件
利用事件冒泡,当子元素的事件触发,会冒泡到父元素
然后去控制相应的子元素
事件委托的作用:
我们只操作了一次 DOM ,提高了程序的性能
动态新创建的子元素,也拥有事件
<ul>
<li>刘德华</li>
<li>刘德华</li>
<li>刘德华</li>
<li>刘德华</li>
<li>刘德华</li>
</ul>
<script>
// 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul')
ul.addEventListener('click', function(e) {
// e.target 这个可以得到我们点击的对象
e.target.style.backgroundColor = 'pink'
})
</script>
8. 鼠标事件
鼠标事件
案例:禁止选中文字和禁止右键菜单
<body>
我是一段不愿意分享的文字
<script>
// 1. contextmenu 我们可以禁用右键菜单
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
})
// 2. 禁止选中文字 selectstart
document.addEventListener('selectstart', function(e) {
e.preventDefault();
})
</script>
</body>
鼠标事件对象
案例:跟随鼠标的天使
<style>
img {
position: absolute;
}
</style>
<img src="images/angel.gif" alt="">
<script>
let pic = document.querySelector('img')
document.addEventListener('mousemove', function(e) {
// 1. mousemove只要我们鼠标移动1px 就会触发这个事件
// 2.核心原理: 每次鼠标移动,我们都会获得最新的鼠标坐标,
// 把这个x和y坐标做为图片的top和left 值就可以移动图片
let x = e.pageX
let y = e.pageY
console.log('x坐标是' + x, 'y坐标是' + y)
//3 . 千万不要忘记给left 和top 添加px 单位
pic.style.left = x + 'px'
pic.style.top = y + 'px'
})
</script>
9. 键盘事件
键盘事件
注意:三个事件的执行顺序是keydown—-keypress—-keyup
**
键盘事件对象
案例:使用keyCode属性判断用户按下哪个键
<script>
// 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
document.addEventListener('keyup', function(e) {
console.log('up:' + e.keyCode)
// 我们可以利用keycode返回的ASCII码值来判断用户按下了那个键
if (e.keyCode === 65) {
console.log('您按下的a键')
} else {
console.log('您没有按下a键')
}
})
document.addEventListener('keypress', function(e) {
// console.log(e)
console.log('press:' + e.keyCode)
})
</script>
案例:模拟京东按键输入内容
需求:当我们按下 s 键, 光标就定位到搜索框(文本框获得焦点)
<input type="text">
<script>
// 获取输入框
let search = document.querySelector('input')
// 给document注册keyup事件
document.addEventListener('keyup', function(e) {
// 判断keyCode的值
if (e.keyCode === 83) {
// 触发输入框的获得焦点事件
search.focus()
}
})
</script>