事件
事件基础
概念
- 事件是指用户跟页面进行交互的各种动作的统称。比如点击、双击、按压键盘、滚轮等。
- 我们可以实现通过事件的处理能够当用户触发某个动作时能够去执行js代码
事件分类
UI:跟用户间接相关的事件:
load
:在资源加载完成之后触发- 只针对window对象以及img标签有效
- window对象即页面加载完成之后触发。如果是img标签,那么表示图片加载完成之后进行触发
resize
:在页面的尺寸发生变化时进行触发标签变量名.onload = function(){
//资源加载完成之后
}
标签变量名.onresize = function(){
//标签尺寸变化时进行触发
}
例子:
window.onload = function(){
//页面的dom结构加载完之后进行触发
}
var img =document.querySelector("img")
img.onload = function(){
图片加载完之后进行触发
}
对于window.onload来说,可以保证里面的代码是在页面dom树加载完之后执行,就避免了head标签里的dom代码会失效。
- resize一般也是针对整个页面
鼠标:
click
:点击事件dblclick
:双击mousemove
:当鼠标在指定标签内部移动时会触发。mouseenter
:当鼠标进入指定标签内部会触发一次。mouseleave
:当鼠标离开指定标签内部会触发一次。<div ondblclick="" onmousemove="" onmouseenter="" onmouseleave=""></div>
标签变量名.ondblclick = function(){
//要执行的代码
}
标签变量名.onmousemove = function(){
//该标签内部移动时会执行
}
标签变量名.onmouseenter = function(){
//进入该标签内部时会执行
}
标签变量名.onmouseleave = function(){
//离开该标签内部时会执行
}
键盘
keydown
:按下键盘任何一个键时会触发keyup
:按下键盘任何一个键完全释放时触发keypress
:按下键盘任何一个键到底部即将释放时触发 ```javascript 标签变量名.onkeydown = function(){
} 标签变量名.onkeypress = function(){
} 标签变量名.onkeyup = function(){
}
- 这三个事件只有keyup可以获取输入框最新的数据,所以一般keyup用的最多。
- 一般我们会用来实时监测用户的输入是否符合要求
-
焦点
- `focus`:一般是表单元素`获取`焦点时触发,比如鼠标点击输入框
- `blur`:一般是表单元素`失去`焦点时触发,比如鼠标点击输入框
```javascript
<div onfocus="" onblur=""></div>
标签变量名.onfocus = function(){
}
标签变量名.onblur = function(){
}
一般用于用户输入监测或改变样式
- 文本
change
:一般针对下拉菜单的,用于当用户切换选项时触发 ```javascript 标签变量名.onchange = function(){
}
-
滚轮
- `mousewheel`:当鼠标滚轮在滚动时进行触发,火狐不兼容
- `DOMMouseScroll`::当鼠标滚轮在滚动时进行触发,火狐兼容
```javascript
<div onmousewheel = ""></div>
标签变量名.onmousewheel = function(){
}
标签变量名.addEventListener("DOMMouseScroll",function(){
})
一般用于实现长列表数据动态加载(参考京东首页数据滚动加载)
- 触摸屏
touchstart
:当触摸屏单个手指点击时触发touchend
::当触摸屏单个手指离开屏幕时触发touchmove
:当触摸屏上的单个手指在屏幕上移动时触发 ```javascript 标签变量名.addEventListener(‘touchstart’,function(){
}) 标签变量名.addEventListener(‘touchend’,function(){
}) 标签变量名.addEventListener(‘touchmove’,function(){
})
<a name="0cc6d5af"></a>
## 事件流
<a name="8e1b944f"></a>
### 背景
- 为了解决针对嵌套标签的事件触发位置问题。所以才有了事件流的概念
<a name="b59c9e0f-1"></a>
### 概念
- 事件流是指事件触发的顺序流向,即谁先触发事件,谁后触发。针对嵌套标签。
- 根据事件触发的顺序不同事件流分为冒泡和捕获
<a name="042772f2"></a>
### 冒泡
- 从具体触发事件的子标签开始冒泡,会依次的去触发父标签及祖先标签的事件。
```javascript
html:
<div class="box-1">div-1
<div class="box-2">div-2
<div class="box-3">div-3
<div class="box-4">div-4
<div class="box-5">div-5</div>
</div>
</div>
</div>
</div>
JavaScript:
给5个div设置事件。对于冒泡来说,触发的事件顺序是box-5 ->box-4->box-3->box-2->box-1->body->html->document对象.由具体的子标签到父标签
捕获
- 从document开始触发事件,一直触发到具体的子标签。
html:
<div class="box-1">div-1
<div class="box-2">div-2
<div class="box-3">div-3
<div class="box-4">div-4
<div class="box-5">div-5</div>
</div>
</div>
</div>
</div>
JavaScript:
给5个div设置事件。对于冒泡来说,触发的事件顺序是box-5 <-box-4<-box-3<-box-2<-box-1<-body<-html<-document对象.由document到body,到具体的子标签
事件执行阶段
概念
- 当用户触发某个事件时,该事件的完整的执行流程就是事件执行流程(阶段)
流程
- 第一阶段:先执行一次捕获,即父标签触发(最顶层能够到document),一直到具体的子标签触发。
- 第二阶段:事件目标阶段:真正用户要执行事件的子标签进行触发
- 第三阶段:执行一次冒泡。由具体的子标签到父标签依次触发
注意点
- 第二阶段:事件目标实际上是将第一阶段的末尾以及第三阶段的开头划分为了第二阶段。只是为了说明目前是对用户真正要执行的标签进行处理。实际第二阶段不会再单独的触发一次
- 实际的事件处理中,只会在捕获或冒泡中二选一,普遍用的最多的是冒泡。
事件处理程序
概念
- 当触发某个事件时要执行的程序(即代码).根据更新分为DOM0级和DOM2级
DOM 0级
1. JavaScript
标签变量名.on事件名 = function(){
}
2. 作为标签的属性
<div on事件名="要执行的代码"></div>
- DOM 0 级只能是在事件执行阶段中的第三阶段处理。
DOM2级
//添加事件处理程序
标签变量名.addEventListener('事件名',事件触发要执行的函数,是否是捕获阶段处理);
第三个参数是布尔型,true表示捕获阶段处理。false表示冒泡阶段处理,默认false。
//删除事件处理程序
标签变量名.removeEventListener('事件名',事件触发要执行的函数,是否是捕获阶段处理);
例子:body设置点击事件的处理程序为handler,捕获阶段处理
document.body.addEventListener('click',handler,true);
//删除
document.body.removeEventListener('click',handler,true);
function handler(){
console.log("body被点击了")
}
- 如果要删除的话,必须保证删除使用 的3个参数和添加时写的3个参数完全一样。第二个参数必须是一个函数名,而不是一个具体的function
DOM2级和DOM0级关于事件处理程序的区别
- dom2级可以选择在捕获阶段或冒泡阶段进行处理。而dom0级只能在冒泡阶段处理
兼容性
- DOM2级只能ie9+支持,DOM0级全系支持
event对象
概念
- JavaScript为了能够在处理事件相关代码时,能够获取该事件的相关信息,JavaScript会在触发某事件时会
自动创建
一个event对象并收集该事件的相关信息,该event对象会作为事件处理函数的实际参数。所以我们在写事件处理代码时需要定义形式参数来接收。 - 接收event对象后,可以使用event对象里所包含的相关内容。比如事件的触发标签,事件类型名,甚至可以控制冒泡行为,获取触发事件时鼠标的所在位置
获取event对象
html :
<div><div>
JavaScript:
var div = document.querySelector('div');
div.addEventListener('click',function(event){
//event参数就保存了该对象
console.log(event);
})
- 每次触发事件时会新建event对象。
常用属性和api
target
:真正触发事件的具体的子标签currentTarget
:当前正在处理的事件标签,因冒泡或捕获,所以实际的标签会不同,不常用stopPropagation()
:取消进一步的冒泡。preventDefault()
:取消事件的默认行为。比如a标签的默认行为是条件,如果调用了该函数后,a标签就不在有跳转功能。表单里的按钮也是一样,调用了该函数后,按钮就不具有表单提交功能。type
:事件的类型名clientX&clientY
:指触发事件时,鼠标在当前窗口中的下标。以屏幕左上角为原点pageX&pageY
:获取鼠标的坐标,以屏幕左上角为原点。跟clientX或 Y
的区别是是以整个HTML文档作为参考
event对象名.target
event对象名.clientX
event对象名.clientY
event对象名.preventDefault();
event对象名.stopPropagation();
事件委托
背景
- 我们在给多个标签设置事件处理程序时,那么相关代码会很多,特别是针对有规律的事件代码,会显的很繁琐。针对代码繁琐,我们可以用事件委托来解决
概念
- 事件委托,又称事件代理。是指利用了事件执行阶段中的冒泡机制以及配合 event对象来达到减少事件处理代码量的一种编程技巧。
作用
- 减少事件处理程序的代码量
- 管理事件处理代码
语法(流程)
- 给需要设置点击事件的标签的父标签或祖先标签设置事件处理程序。
- 利用
event.target
来判断真正触发事件的具体子标签。然后针对该子标签执行相应代码
// document.querySelector('.box1').addEventListener('click',function(e){
// console.log(e.target);
// })
// document.querySelector('.box2').addEventListener('click',function(e){
// console.log(e.target);
// })
//事件委托
document.body.addEventListener('click',function(e){
//区分:class id nodeName
var classname = e.target.getAttribute('class');
if(classname=='box1'){
//点击了box1 div
//执行box1的点击事件代码
console.log('点击了box1')
}else if(classname=='box2'){
//点击了box1 div
//执行box1的点击事件代码
console.log('点击了box2')
}
});
扩展:
表单提交或重置
submit()
reset()
:
html:
<form action="success.html" id="loginForm">
用户名: <input type="text" id="user">
密码:<input type="text" id="pass">
<button id="login-btn">登录</button>
</form>
JavaScript:
var form = document.querySelector("#loginForm");
提交: form.submit();
重置: form.reset();