概念
用户的一切操作称为一个事件,事件就对应着用户的行为,所以可以通过事件来监听用户的行为。
事件的添加
方式一:
在标签中添加
<button onclick="fn()">按钮</button>
<script>
function fn(){
console.log("我是按钮执行的事件")
}
</script>
方式二:
通过DOM元素添加
<button>按钮</button>
var btn=document.querySelector("button");
btn.onclick=function (){
console.log("我是通过DOM元素添加的事件!")
}
如果用此方法添加了多个事件,则只执行最后一个事件。移除这种方式的事件可以用removeAttribute方式移除,也可以用setAttribute方式将onclick设置为空。
方式三:
使用addEventListener方法
<button>按钮</button>
var btn=document.querySelector("button");
btn.addEventListener("click",function(){
console.log("我是通过addEventListener方法添加的事件")
}
)
注意:addEventListener参数说明:
第一个参数:表示事件名称,用字符串形式;
第二个参数:表示事件对应的执行函数,可以是一个函数名,也可以是一个匿名函数。
addEventListener可以绑定多个不同的函数,如果要移除这种方式的事件,则需要使用removeEventListener方法移除绑定的事件函数,而且移除的监听函数参数必须和添加监听函数时的参数完全一致,否则无效;移除多个需要一个一个的移除。
如果使用方式二和方式三同时添加事件,那么这个事件将被重复执行,执行顺序是就近原则。
事件的传播
当一个事件发生以后,它会在不同的DOM节点之间传播,这种传播会使得一个事件在多个节点上触发。
1.事件传播的三个阶段
第一阶段:从window对象传导到目标节点,称为“捕获阶段”。
第二阶段:在目标节点上触发,称为“目标阶段”。
第三阶段;从目标节点传导回window,称为“冒泡阶段”。
说明:事件传导的最顶层是window,接着是document>html>body。
2.我们绑定的事件函数,默认会在冒泡阶段触发。
3.addEventListener方法的第三个参数
它的第三个参数表示监听函数在捕获阶段触发还是在冒泡阶段触发,用一个布尔值表示,false表示在冒泡阶段触发,true表示在捕获阶段触发。如果在冒泡阶段和捕获阶段都进行事件的监听,每个祖先级节点都会触发两次,先绑定谁就先执行谁。
事件对象
1.什么是事件对象?
当用户进行了某个行为,而这个行为被绑定成函数事件时,那么这个函数事件内部会发生一个对象(event),这个对象包含了这个被触发的事件的所有相关信息,然后这个对象就被称为事件对象。
获取事件对象
一般一个函数事件的第一个形参就是此函数的事件对象,也可以通过event获取。
2.通过事件对象实现一些常见功能
①通过事件对象阻止事件的默认行为 -------------------> event.preventDefault();
<a href="https://www.baidu.com/">百度</a>
var aBtn=document.querySelector("a");
aBtn.onclick=function (){
event.preventDefault();
}
此时点击上面的a标签将不会跳转到百度页面。
②通过事件对象阻止冒泡行为 -------------------> event.stopPropagation();
③通过事件对象获取当前坐标
event.clientX | 所点击位置到可视区域的横轴距离 |
event.clientY | 所点击位置到可视区域的纵轴距离 |
event.screenX | 所点击位置到显示屏的横轴距离 |
event.screenY | 所点击位置到显示屏的纵轴距离 |
event.offsetX | 所点击位置到所点击元素左上角的横轴距离 |
event.offsetY | 所点击位置到所点击元素左上角的纵轴距离 |
事件代理
1.事件代理 又称为 事件委托,它是通过事件会在冒泡阶段向上传播到祖先节点,因此可以把后代节点的监听函数胡定义在祖先节点上,由祖先节点的监听函数统一处理多个后代元素的事件。
2.作用与好处:
①减少了事件判定,极大的提高了性能,对于移动端应用尤为友好;
②解决了麻烦,对于后面添加的元素我们原先绑定的事件会无效,这时可以通过事件代理来解决。
3.常见的事件类型
鼠标事件
鼠标左键单击事件 click
鼠标左键双击事件 dblclick
鼠标右击事件 contextmenu
鼠标移入事件:mouseover
鼠标移出事件:mouseout
如果div中有个p标签,然后给div绑定了这两个事件,那么移入到div中会触发移入事件,移除div会触发移除事件,这个不用说。
需要注意的是,当我们移入到div中的子标签p中时,会依次执行移出移入事件。
鼠标移入事件: mouseenter
鼠标移出事件: mouseleave
mouseout事件会冒泡,mouseleave事件不会。
鼠标按下事件 mousedown
鼠标释放事件 mouseup
当我们点击一个按钮时,触发顺序为:
mousedown首先触发,mouseup接着触发,click最后触发。
鼠标持续移动事件mousemove
为了避免性能问题,建议对mousemove事件的监听函数做一些限定,比如限定一段时间内只能运行一次代码。
键盘事件
keydown事件: 键盘按一下事件(如果按着不放会连续触发此事件)
keypress事件:键盘按一下事件(如果按着不放会连续触发此事件)
如果两个事件都给了,那么当绑定元素聚焦后按一下键盘,两个方法都会触发
如果按着不放,那么这两个事件会连续不断的不断触发keydown -> keypress
如果按下按的键是Ctrl、Alt、Shift和Meta等,那么keypress不会被触发,只有keydown会不断的触发
keyup事件:键盘松开事件
如果用户一直不松开键盘,键盘事件就会按照这样的顺序连续触发:keydown -> keypress -> keydown-> keypress -> ... (松开键盘后)-> keyup。
获取当前按下的按键值
基本演示
当用户在按下键盘的过程中(keydown事件和keyup事件)可以通过事件对象的keyCode属性获取当前键盘的值,返回的值是一个数字。可以根据获取的数字做出判断来完成特定的事件函数。
键盘各键对应的数字值
表单事件
表单事件表示的是当HTML的<form>标签内的元素被操作后发生的事件,在HTML中常见的表单标签有<input>(不同的“type”属性支持的事件可能会有区别)、<select>、<textarea>、<button>等,这些元素在内容在被操作或值发生改变时都会触发事件。
表单元素主要有以下事件:
input事件
input事件当<input>、<textarea>的值发生变化时触发。此外,将contenteditable属性设置为“true”的非表单元素,只要值发生变化,也会触发input事件。input事件的一个特点,就是会连续触发,比如用户每次按下一次按键,就会触发一次input事件。
Change事件
Change事件当<input>(单选框和复选框)、<select>、<textarea>(需要失去焦点时触发)的值发生变化时触发。它与input事件的最大不同,就是不会连续触发,只有当全部修改完成时才会触发,而且input事件必然会引发change事件。
select事件
select事件当在<input>、<textarea>中选中文本时触发。
reset事件
reset事件只能发生在表单元素<form>上,当表单重置(所有表单成员变回默认值)时触发。
submit事件
submit事件只能发生在表单元素<form>上,当表单数据向服务器提交时触发。注意,submit事件的发生对象是<form>,而不是<button>,因为提交的是表单,而不是按钮。
文档事件
文档事件就是DOM元素在特定的操作下一种事件,有的时候并非需要人为的操作,如页面加载时就会触发加载事件,页面将关掉时会触发卸载事件。又如,元素在获得焦点时会触发获得焦点事件,失去焦点又会触发失去焦点事件等。
load事件和error事件
load事件在页面加载成功时触发,
error事件在页面加载失败时触发。
- 页面从浏览器缓存加载,并不会触发load事件。
- 这两个事件实际上属于进度事件,不仅发生在document对象,还发生在各种外部资源上面。
- 浏览网页就是一个加载各种资源的过程,图像、样式表、脚本、视频、音频、Ajax请求等等。
- 这些资源和document对象、window对象、XMLHttpRequestUpload对象,都会触发load事件和error事件。
unload事件
unload事件在窗口关闭或者document对象将要卸载时触发,发生在window、body、frameset等对象上面。
它的触发顺序排在beforeunload、pagehide事件后面。
unload事件只在页面没有被浏览器缓存时才会触发,换言之,如果通过按下“前进/后退”导致页面卸载,并不会触发unload事件。
DOMContentLoaded事件
当HTML文档下载并解析完成以后,就会在document对象上触发DOMContentLoaded事件。
这时,仅仅完成了HTML文档的解析(整张页面的DOM生成),所有外部资源(样式表、脚本、iframe等等)可能还没有下载结束。也就是说,这个事件比load事件,发生时间早得多。
需要注意的是,网页的JavaScript脚本是同步执行的,所以定义DOMContentLoaded事件的监听函数,应该放在所有脚本的最前面。否则脚本一旦发生堵塞,将推迟触发DOMContentLoaded事件。
readystatechange事件
readystatechange事件发生在Document对象和XMLHttpRequest对象加载完成后,当它们的readyState属性发生变化时触发。
IE8不支持DOMContentLoaded事件,但是支持这个事件。因此,可以使用readystatechange事件,在低版本的IE中代替DOMContentLoaded事件。
scroll事件
scroll事件在文档或文档元素滚动时触发,可以是鼠标滚轮触发的滚动,也可以是用户用鼠标拖动滚动条。
resize事件
resize事件在改变浏览器窗口大小时触发,可以发生在window、body对象上面。
focus事件和focusin事件
当元素(主要是<a<和表单元素)在获得焦点的时候触发,区别在于focus事件不会冒泡,而focusin事件(老版火狐浏览器不支持)会冒泡。focusin事件发生在focus事件之前。
blur事件和focusout事件
当元素在去焦点的时候触发,区别在于blur事件不会冒泡,而focusout事件(老版火狐浏览器不支持)会冒泡。focusout事件发生在blur事件之前。
这两个事件对象也含有一个target属性,返回内容同上