事件
事件
注册事件
-
给元素添加事件,称为注册事件或者绑定事件
-
注册事件有两种方式:
- 传统方式
- 方法监听注册方式
-
传统注册方式
- 利用on开头的事件 onclick
<button onclick= "alert('hi')"></button>
btn.onclick = function() {}
- 特点:注册事件的唯一性
- 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数
-
方法监听注册方式
- W3C 标准 推荐方式
- addEventListener()它是一个方法
- IE9之前的IE不支持此方法,可使用attachEvuent()代替
- 特点:同一个元素同一个时间可以注册多个监听器
- 按注册顺序依此执行
-
addEventListener
事件监听方式
eventTarget.addEventListener(type, listener[, useCapture])
-
eventTarget.addEventListener()
方法将指定的监听器注册到eventTarget
(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数 -
同一个元素,同一个事件可以添加多个侦听器(事件处理程序)
-
该方法接受三个参数:
type:
事件类型字符串,比如clcik、 mouseover
,注意这里不要带on
listener:
事件处理函数,事件发生时,会调用该监听函数useCapture:
可选参数,是一个布尔值,默认是false
-
代码演示
<button>传统注册事件</button>
<button>方法监听注册事件</button>
<script>
const btns = document.querySelectorAll('button');
//1. 传统注册事件
btns[0].onclick = function() {
console.log("传统注册事件");
}
btns[0].onclick = function() {
console.log("传统注册事件2");
}
//2. 方法监听注册事件
btns[1].addEventListener('click', function() {
console.log('方法监听注册事件');
})
btns[1].addEventListener('click', function() {
console.log('方法监听注册事件2');
})
</script>
-
attachEvent
事件监听方式 -
eventTarget.attachEvent()
方法将指定的监听器注册到eventTarget
(目标对象)上,当该对象触发指定的事件时,指定的回调函数就会被执行 -
该方法接受两个参数
enentNameWithOn:
事件类型字符串,比如clcik、 mouseover
,这里要带on
callback:
事件处理函数,当目标触发事件时回调函数被调用
-
注册事件兼容性解决方案
function addEventListener(element, eventName, fn) {
//判断当前游览器是否支持 addEventListener 方法
if (element.addEventListener1) {
element.addEventListener(eventName, fn);//第三个参数默认为false
}else if(element.attchEvent) {
element.attachEvent('on' + eventName, fn);
}else {
// 相当于 element.oclick = fn;
element['on' + eventName] = fn;
}
}
- 兼容性处理的原则,首先照顾大多游览器,再处理特殊游览器
删除事件(解绑事件)
-
解绑事件的方式
-
传统注册方式
evenTarget.onclick = null;
-
方法监听注册方式
evenTarget.removeEventListener(type, listener[, useCapture])
evenTarget.detachEvent(enentNameWithOn, callback);
-
代码演示
const btns = document.querySelectorAll('button');
//1. evenTarget.onclick = null; 删除事件
btns[0].onclick = function() {
console.log("传统注册事件");
btns[0].onclick = null
}
//2. evenTarget.removeEventListener() 删除事件
btns[1].addEventListener('click', fn)//里面的fn不需要调用小括号
function fn() {
console.log('方法监听注册事件');
btns[1].removeEventListener('click', fn)
}
DOM 事件流
-
事件流描述的时从页面中接受事件的顺序
-
事件发生时会在元素节点之间按照特点的顺序传播,这个传播过程即DOM事件流
-
比如我们给一个div注册了点击事件:
-
DOM 事件流分为3个阶段
- 捕获阶段
- 当前目标阶段
- 冒泡阶段
-
事件冒泡: IE 最早提出,事件开始由最具体的元素接受,然后逐级向上传播到DOM最顶层节点的过程
-
事件捕获: 网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到最具体的元素接受的过程
-
注意
- JS代码中只能执行捕获或者冒泡其中一个阶段
onclick
和attachEvent
只能得到冒泡阶段addEventListener(type, listener[, useCapture])
- 第三个参数如果是
true
,表示再事件捕获阶段调用事件处理程序 - 第三个参数如果是
false
(不写默认为false
),表示在事件冒泡阶段调用事件处理程序
- 第三个参数如果是
- 实际开发我们很少使用时间捕获,我们更关注于冒泡
- 有些事件时没有冒泡的,比如
onblur
onfocus
onmouseenter
onmouseleave
-
代码演示
-
捕获阶段
<div class="body">body盒子
<div class="html">html盒子
<div class="div">div盒子</div>
</div>
</div>
<script>
const div = document.querySelector('.div')
div.addEventListener('click', function() {
console.log("div");
},true)
const body = document.querySelector('.body')
body.addEventListener('click', function() {
console.log("body");
},true)
const html = document.querySelector('.html')
html.addEventListener('click', function() {
console.log("html");
},true)
document.addEventListener('click', function() {
console.log("document");
},true)
</script>
-
接下来我们点击div盒子
-
发现打印顺序是从上往下渗透
- document -> html -> body -> div
-
然后我们将true改为false或者删除(默认false)
-
这里代码不做演示
-
然后我们点击div盒子
-
发现打印顺序是从下往上冒泡
- div -> body -> html -> document
事件对象
div.onclick = function(event) {}
eventTarget.onclick = function('click', function(event) {})
- event就是一个事件对象,写到我们侦听器函数的小括号里面当形参来看
- 事件对象只有有了事件才会存在,他是系统给我们自动创建的,不需要我们传递参数
- 事件对象时我们事件的一系列相关数据的集合,更事件相关的
- 比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标等
- 比如键盘事件里面就包含了键盘事件的信息,判断用户按下了哪个键等
- 这个事件对象可以自己命名,常见
event 、evt 、 e
- 事件对象也有兼容性问题 IE678 通过
window.event
- 兼容性写法
e = e || window.event
- 兼容性写法
- 官方解释:event对象代表事件的状态,比如键盘的状态,鼠标的位置,鼠标按钮的状态
- 简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放在这个对象里面,这个对象就是事件对象event,它有很对属性和方法
事件对象常见的属性和方法
- 所有的属性和方法都写在函数里面
返回触发事件的对象
e.target
返回触发事件的对象e.target
返回触发事件的对象IE678- 和
this
的区别e.target
及e.target
点击了那个元素,就返回那个元素this
那个元素绑定了这个点击事件,就返回谁
返回事件的类型
e.type
返回事件的类型,比如click、mouseover 不带on
止默认(行为)事件
e.preventDefault
该方法阻止默认(行为)事件e.returnValue
该属性阻止默认(行为)事件IE678return false
也能阻止默认(行为)事件,也没有兼容性问题,但是要注意return后面的代码不执行了
阻止冒泡
e.stopPropagation()
该方法阻止事件冒泡cancelBubble = true
该属性阻止事件冒泡IE678- 阻止冒泡的兼容性解决方案
if(e && e.stopPropagation) {
e.stopPropagation();
}else {
window.event.cancelBubble = true;
}
事件委托
- 事件委托也称之为事件代理,在jQuery里面称为事件委派
事件委托的原理
- 不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
事件委托的作用
- 我们只操作了一次DOM,提高了程序的性能
<ul>
<li>老大</li>
<li>老二</li>
<li>老三</li>
<li>老四</li>
<li>老五</li>
</ul>
<script>
const ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
//e.target 这个可以得到我们点击的对象
e.target.style.backgroundColor = 'green'
})
</script>
常见的鼠标事件
onclick
当鼠标点击左键触发ondblclick
当鼠标双击左键触发ondrag
当拖动元素时触发ondragend
当拖动操作结束时触发ondragenter
当元素被拖动至有效的拖放目标时触发ondragleave
当元素离开有效拖放目标时触发ondragover
当元素被拖动至有效拖放目标上方时触发ondragstart
当拖动操作开始时触发ondrop
当被拖动元素正在被拖放时触发onmousedown
当按下鼠标按钮时触发onmousemove
当鼠标指针移动时触发onmouseout
当鼠标指针移出元素时触发onmouseover
当鼠标指针移至元素之上时触发onmouseup
当松开鼠标按钮时触发onmousewheel
当转动鼠标滚轮时触发onscroll
当滚动元素的滚动条时触发
禁止鼠标右键菜单
contextmenu
主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
})
禁止鼠标选中文字
selectstart
document.addEventListener('selectstart', function(e) {
e.preventDefault();
})
鼠标事件对象(MouseEvent)Y
e.clientX
返回鼠标相对于游览器窗口(可视区)的X坐标e.clientY
返回鼠标相对于游览器窗口(可视区)的Y坐标e.pageX
返回鼠标相对于文档页面的X坐标IE9+支持e.pageY
返回鼠标相对于文档页面的X坐标IE9+支持e.screenX
返回鼠标相对于电脑屏幕的X坐标Ye.screenY
返回鼠标相对于电脑屏幕的Y坐标
常用的键盘事件
onkeyup
某个键盘按键被松开时触发onkeydown
某个键盘按键被按下时触发onkeypress
某个键盘按键被按下时触发但是它不能识别功能键,比如ctrl shift
箭头等- 注意
- 如果使用
addEventListener
不需要加on
- 三个事件的执行顺序
keydown
--keypress
--keyup
- 如果使用
键盘事件对象
-
keyCode
返回该键的ASCll值、
-
注意
onkeydown
和onkeyup
不区分大小写,keypress
区分大小写- 在我们实际开发中,我们更多的使用
onkeydown
和onkeyup
,它们能识别所有的键(包括功能键) keypress
不能识别功能键,但是keyCode
属性能区分大小写,返回不同的ASCll值
本文来自博客园,作者:懒惰ing,转载请注明原文链接:https://www.cnblogs.com/landuo629/p/12506862.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?