事件监听
- DOM允许我们书写JavaScript代码以让HTML元素对事件作出反应
- 什么是“事件”:用户与网页的交互动作
- “监听”,顾名思义,就是让计算机随时能够发现这个事件发生了,从而执行程序员预先编写的一些程序
- 设置事件监听的方法主要有onxxx和addEventListener()
- 两种,二者的区别将在“事件传播”一课中介绍最简单的给元素设置事件监听的方法就是设置它们的onxxx属性,像这样:
常见的鼠标事件监听
事件名 | 事件描述 |
---|---|
onclick | 当鼠标单击某个对象 |
ondblclick | 当鼠标双击某个对象 |
onmousedown | 当某个鼠标按键在某个对象上被按下 |
onmouseup | 当某个鼠标按键在某个对象上被松开 |
onmousemove | 当某个鼠标按键在某个对象上被移动 |
onmouseenter | 当鼠标进入某个对象(相似事件onmouseover) |
onmouseleave | 当鼠标离开某个对象(相似事件onmouseout) |
常见的键盘事件监听
事件名 | 事件描述 |
---|---|
onkeypress | 当某个键盘的键被按下(系统按钮如箭头键和功能键无法得到识别) |
onkeydown | 当某个键盘的键被按下(系统按钮可以识别,并且会先于onkeypress发生) |
onkeyup | 当某个键盘的键被松开 |
常见的表单事件监听
事件名 | 事件描述 |
---|---|
onchange | 当用户改变域的内容 |
onfocus | 当某元素获得焦点(比如tab键或鼠标点击) |
onblur | 当某元素失去焦点 |
onsubmit | 当表单被提交 |
onreset | 当表单被重置 |
常见的页面事件监听
事件名 | 事件描述 |
---|---|
onload | 当页面或图像被完成加载 |
onunload | 当用户退出页面 |
当盒子嵌套时事件监听的执行顺序
- 事件的传播是从内到外的
- onxxx这样的写法只能监听冒泡阶段
- DOM0级事件监听:只能监听冒泡阶段
oBox.onclick = function () {
};
- DOM2级事件监听:
oBox.addEventListener('click', function () {
// 这是事件处理函数
}, true);
- 最内部元素不再区分捕获和冒泡阶段,会先执行写在前面的监听,然后执行后写的监听
- 如果给元素设置相同的两个或多个同名事件,则DOM0级写法后面写的会覆盖先写的;而DOM2级会按顺序执行
什么是事件对象
- 事件处理函数提供一个形式参数,它是一个对象,封装了本次事件的细节
- 这个参数通常用单词event或字母e来表示
oBox.onmousemove = function (e) {
// 对象e就是这次事件的“事件对象”
};
鼠标位置
属性 | 属性描述 |
---|---|
clientX | 鼠标指针相对于浏览器的水平坐标 |
clientY | 鼠标指针相对于浏览器的垂直坐标 |
pageX | 鼠标指针相对于整张网页的水平坐标 |
pageY | 鼠标指针相对于整张网页的垂直坐标 |
offsetX | 鼠标指针相对于事件源元素的水平坐标 |
offsetY | 鼠标指针相对于事件源元素的垂直坐标 |
e.charCode和e.keyCode属性
- e.charCode属性通常用于onkeypress事件中,表示用户输入的字符的“字符码”
- e.keyCode属性通常用于onkeydown事件和onkeyup中,表示用户按下的按键的“键码”
charCode字符码
字符 | 字符码 |
---|---|
数字0 ~ 数字9 | 48 ~ 57 |
大写字母A ~ Z | 65 ~ 90 |
小写字母a ~ z | 97 ~ 122 |
keyCode键码
按键 | 键码 |
---|---|
数字0 ~ 数字9 | 48 ~ 57(同charCode键码完全相同) |
字母不分大小a ~ z | 65 ~ 90(同charCode键码的大写字母A ~ Z,而keyCode不分大小写,一律为65 ~ 90) |
四个方向键← ↑ → ↓ | 37、38、39、40 |
回车键 | 13 |
空格键 | 32 |
e.preventDefault()方法
- e.preventDefault()方法用来阻止事件产生的“默认动作”
- 一些特殊的业务需求,需要阻止事件的“默认动作”
e. stopPropagation()方法
e.stopPropagation()方法用来阻止事件继续传播
在一些场合,非常有必要切断事件继续传播,否则会造成页
面特效显示出bug
批量添加事件监听的性能问题
每一个事件监听注册都会消耗一定的系统内存,而批量添加事件会导致监听数量太多,内存消耗会非常大
实际上,每个
- 的事件处理函数都是不同的函数,这些函数本身也会占用内存
-
动态绑定事件的问题
新增元素必须分别添加事件监听,不能自动获得事件监听
大量事件监听、大量事件处理函数都会产生大量消耗内存
事件委托
利用事件冒泡机制,将后代元素事件委托给祖先元素<ul id="list"> <li>列表项</li> <li>列表项</li> <li>列表项</li> <li>列表项</li> <li>列表项</li> </ul>
监听onclick事件
不管点击任何一个 - 元素,事件都会通过事件冒泡传给祖先元素
e.target和e.currentTarget属性 -
属性 属性描述 target 触发此事件的最早元素,即“事件源元素” currentTarget 事件处理程序附加到的元素 事件委托通常需要结合使用e.target属性
事件委托的使用场景
当有大量类似元素需要批量添加事件监听时,使用事件委
托可以减少内存开销
当有动态元素节点上树时,使用事件委托可以让新上树的
元素具有事件监听使用事件委托时需要注意的事项
- onmouseenter和onmouseover都表示“鼠标进入”,它们有什么区别呢?
答:onmouseenter不冒泡,onmouseover冒泡。 - 使用事件委托时要注意:不能委托不冒泡的事件给祖先元素
- 最内层元素不能再有额外的内层元素了,比如:
<ul id="list"> <li><span>我是span</span>列表项</li> <li><span>我是span</span>列表项</li> <li><span>我是span</span>列表项</li> </ul>
- onmouseenter和onmouseover都表示“鼠标进入”,它们有什么区别呢?