事件:系统内发生的动作或事情
- 用户触发:鼠标点击、滚动、拖拽、键盘按下
- 系统生成:文档或图片加载完成、动画结束、视频播放暂停
- JS出发:例如调用HTMLElemeng.click()
- 创建自定义事件,并触发EventTarget.dispatchEvent()
1)设置事件监听函数;2)事件触发被监听函数响应
示例:
<div class="box"></div>
<style>
.box{
width: 120px;
height: 120px;
background-color: rgba(165, 42, 2);
cursor: pointer;
}
</style>
<script>
function rand(num){
return Math.floor(Math.random()*num)
}
document.querySelector('.box').addEventListener('click', function(){ //两个参数,要监听的事件类型和一个函数;函数可以单独声明,在里面写函数名不写(),如果函数后跟()则该函数会立即执行
this.style.backgroundColor = `rgb(${rand(256)},${rand(256)},${rand(256)})` //this代表querySelector选中的对象
})
</script>
事件绑定
- 方法
- node.onclick = fun() { ... }
- node.addEventListener('click', fun() { ... })
- 区别
- onclick绑定是赋值,多次相同赋值会覆盖,只有最后一次生效
- addEventListener 是函数执行,可执行/绑定多次,且功能更强大
let obj = {}
obj.onclick = function(num){
console.log(num);
}
obj.onclick = function(str){
console.log(str);
}
console.log(obj.onClick); //打印出第二个函数,因为第二个赋值覆盖掉第一个赋值,只有最后一次生效
this与事件对象
事件传递的函数会有一个形参
<div class="box"></div>
let $box = document.querySelector('.box')
$box.onclick = function(event){
console.log(event); //event是事件对象
console.log(this); //this代表$box
}
- 事件对象包括clientX: 14, clientY: 54, (事件的位置、事件的来源、按了哪个键等这些信息
- 事件绑定时
- 普通函数里面的this代表事件绑定的对象
- 箭头函数里面的this代表外面的this 即window 因为箭头函数没有自己的this
- 在非严格模式下,this是undefined
$box.onclick = (evt) => {
console.log(this); //打印出该页面(Window
}
事件流
- 事件传播有三个阶段
1-3是事件捕获阶段
3-4是目标阶段
4-7是事件冒泡阶段
addEventListener 详细用法
target.addEventListener(type, listener, useCapture)
- type 事件类型 如click等
- listener 事件处理方法 通常为一个函数
- useCapture 可选,默认false,true表示在捕获阶段调用listener,false表示冒泡阶段处理
target.addEventListener(type, listener(e), options)
- options:可选 {capture:是否捕获阶段监听;once:是否只监听一次;passive:是否忽略preventDefault,用于提升移动端性能
- once即只响应一次
- e.target代表点击的对象
target.removeEventlistener 用于解除事件绑定
- 如 target.removeEventListener('click', handler)
事件冒泡
- stopPropagation 阻止事件继续往外传播 用法
target.onclick = (e) => { e.stopPropagation() } //阻止该事件往外传播
- e.preventDefault() 阻止默认事件发生(如点击a链接跳转
<a href="https://baidu.com" alt="百度">百度一下</a>
<a href="https://bilibili.com" alt="bilibili">bilibili</a>
const $$ = s => document.querySelectorAll(s)
$$('a').forEach($a => {
$a.addEventListener('click', function(e){
let href = this.getAttribute('href')
if(href.includes('baidu.com')){
e.preventDefault()
if(confirm('要打开百度吗?')){
location.href = href
}
}
})
})
事件代理/委托
- 事件绑定代理给父元素,由父元素根据事件来源统一处理
- 适用于可能会新增子元素的场景
- 事件代理实际上是事件冒泡的应用
如,任何事件都会冒泡到document阶段,可以在document上绑定事件,通过e.target判断事件发生在哪个区域