事件监听
为 HTML 页面指定标签绑定指定事件,可以通过以下三种方式实现:
- HTML 标签的事件属性(onclick=fn()): 这种方式 HTML 代码和 JavaScript 逻辑不能很好地分离,所以不建议使用。
- DOM 标准的事件(element.onclick=function(){}): 这种方式只能为指定的一个标签绑定一个事件,并且只能具有一个事件处理函数。
- 事件监听器: 这种方式是目前最受欢迎的一种方式。但 IE 8 及之前的版本不支持!
1 | /* |
事件监听器
addEventListener()方法
DOM 提供了事件监听器,可以同时绑定多个事件,并且具有多个事件处理函数。具体监听器语法如下:
element.addEventListener(eventName, functionName, boolean)
参数 | 说明 |
---|---|
eventName | 为元素指定具体的事件名称(例如单击事件是 click 等) |
functionName | 绑定事件的处理函数 |
boolean | 设置事件是捕获阶段还是冒泡阶段。为 false 时为冒泡阶段,一般都是这个值 |
1 | /* |
removeEventListener()方法
移除事件监听器
removeEventListener(eventName, functionName, boolean)
1 | /* |
attachEvent()方法
IE 8 及之前的版本浏览器并不支持 addEventListener() 方法,而提供了如下方法实现
element.attachEvent(eventName, functionName)
参数 | 说明 |
---|---|
eventName | 为元素指定具体的事件名称(例如单件事件是 onclick 等) |
functionName | 绑定事件的处理函数 |
值得注意的是: attachEvent() 方法的 eventName 参数与 addEventListener() 方法的 eventName 参数不同
监听器的兼容方案
1 | function bind(elem, event, callback){ |
注意:在 addEventListener() 方法中的 this 和在 attachEvent() 方法中的 this 指代不同。
通过 addEventListener() 方法为 HTML 页面的标签绑定事件时,this 关键字指代绑定该事件的标签元素。
通过 attachEvent() 方法为 HTML 页面的标签绑定事件时,this 关键字指代绑定 window 对象。
事件对象event
HTML 页面的标签绑定事件的处理函数中,提供了一个事件对象(event)。这个事件对象会返回关于该事件的信息,以及该事件绑定在哪个元素中。
事件对象是以事件的处理函数中的参数形式出现,并不需要我们自己创建,直接使用即可。
1 | element.addEventListener(eventName, function(event){ |
兼容的事件对象
使用 DOM 标准的事件绑定时,Event 事件对象在 IE 8 及之前的版本浏览器情况有所不同。
IE 9 及之后的版本和其他浏览器: 通过事件的处理函数的形参直接得到 Event 对象。
1
2
3
4var btn = document.getElementById('btn');
btn.onclick = function(event){
console.log(event)
}IE 8 及之前的版本浏览器: Event 事件对象被提供在 window 对象中。event对象为全局作用域对象。
1
2
3
4var btn = document.getElementById('btn');
btn.onclick = function(event){
console.log(window.event)
}
想要实现 Event 事件对象的兼容,我们可以在事件的处理函数中添加以下代码:
event = event || window.event;
测试时发现,不在事件的处理函数中添加形参event,函数中也可以使用,这种方式是不严格的,在Firefox浏览器中会报错:
1 | var btn = document.getElementById('btn'); |
事件的目标元素
Event 事件对象提供了 target 属性用于获取触发事件的目标元素(标签)。
IE 8 及之前的版本浏览器不支持 target 属性,而是提供了 srcElement 属性进行替换。
解决方案:
var target = event.target || event.srcElement;
this与event.target的区别
- event.target - 获取触发当前事件的元素
- this - 获取绑定当前事件的元素
阻止默认行为
HTML 页面的一些标签具有默认行为。所谓默认行为,就是不用编写 JavaScript 代码就可以实现的动态效果。例如如下标签:
- a 标签: 用户点击 a 标签,会发生页面跳转行为。
- form 标签: 用户点击表单的提交按钮,表单会发生提交行为。
阻止默认行为,就是不让 HTML 页面这些标签的默认行为发生。想要阻止默认行为可以通过 Event 事件对象提供的属性实现:
- IE 8 及之前版本的浏览器: returnValue 属性 – event.returnValue=false。也可以直接通过return false阻止。
- IE 9 及之后版本和其他浏览器: preventDefault() 方法
1 | function bind(elem, eventName, functionName) { |
获取鼠标坐标
当 HTML 页面中标签绑定的事件被触发时,我们还可以通过 Event 事件对象获取鼠标当前的坐标值。
- x和y - 结果等同于clientX和clientY
- pageX和pageY - 鼠标相对于当前整个页面的坐标值。如果页面过大(存在滚动条),部分页面可能存在可视区域之外。
- clientX和clientY - 鼠标相对于当前窗口可视区域的坐标值
- screenX和screenY - 鼠标相对于当前屏幕的坐标值,从屏幕(不是浏览器)的左上角开始计算。
- offsetX和offsetY - 鼠标相对于指定元素的坐标值(发生事件的地点在事件源元素的坐标系统中的 x 坐标和 y 坐标。)如果是div绑定的事件,则是鼠标相对于该div左上角的位移。
事件周期
根据 W3C 标准事件的发生流程可以分为捕获阶段、触发阶段以及冒泡阶段。
- 捕获阶段: 事件根据 DOM 树结构从最上层节点向下传播,直到绑定该事件节点为止。
- 触发阶段: 事件发生,执行对应的处理函数的逻辑代码。
- 冒泡阶段: 事件根据 DOM 树结构从绑定事件节点向上传播。
如果 addEventListener() 方法的第三个参数值为 true,表示捕获阶段
如果 addEventListener() 方法的第三个参数值为 false(默认值),表示冒泡阶段
值得注意的是: IE 8 及之前版本的浏览器不支持捕获阶段。
捕获阶段和冒泡阶段,相当于实现了父子关系的元素的事件的继承。触发子元素的事件函数时,父元素的事件函数也会触发。
定义父子关系的 div:#d1、#d2,为d1和d2分别绑定事件:
- 因为冒泡阶段的存在,当点击d2时,会先执行d2的事件函数,再执行d1的事件函数。
- 如果使用elem.addEventListener()绑定事件时,第三个参数设置为true,表示捕获阶段,则点击d2时,会先执行d1的事件函数,再执行d2的事件函数。
阻止事件冒泡
如果在上述示例中的冒泡阶段,我们可以看到事件会从最底层节点向上传播。如果只想触发当前节点的事件,而不继续向上冒泡,我们可以通过 Event 事件对象提供的属性来完成:
- IE 8 及之前版本的浏览器: cancelBubble 属性设置为true
- IE 9 及之后版本和其他浏览器: stopPropagation() 方法
注意 以下代码中,将addEventListener第三个参数设置为true,stopPropagation()方法在浏览器中可以阻止事件捕获,这是浏览器的原因,在标准规范中,stopPropagation方法只用来阻止事件冒泡。
1 | // HTML |
事件委托
原本将事件绑定给指定元素,实际上委托给另一个元素,完成事件的绑定和触发。
实现步骤
- 将事件绑定给共同的祖先节点
- 判断触发事件的元素必须原本的元素
1 | <button id="btn" class="btn btn-primary">添加</button> |
滚轮事件
- onscroll事件 - 1. 滚轮事件,2. 滚动条事件
- onmousewheel事件 - 滚轮事件
onmousewheel事件为新增事件,只有Chrome浏览器支持
键盘事件
- onkeydown - 表示键盘被按下
- onkeyup - 表示键盘被释放
- onkeypress - 表示键盘被按一下
获取对应按键
- event.keyCode 属性(建议使用)
- event.which 属性
- event.key 属性
注意:以上三个属性IE 8 及以下版本都不支持
1 | var data = document.getElementById('data'); |
如上代码,按下按键,依次显示keyCode、which、key三个属性:
按键 | keyCode | which | key |
---|---|---|---|
a | 65 | 65 | a |
z | 90 | 90 | z |
0 | 48 | 48 | 0 |
9 | 57 | 57 | 9 |
pageup | 38 | 38 | 其他浏览器:ArrowUp IE9-11: Up |
鼠标事件
event的button属性
可以通过 event.button 得到鼠标点击的是左键或右键(IE 8 浏览器不适用)
- 0:左键
- 1:中间的滚轮键
- 2:右键
阻止点击右键默认菜单
1 | // TODO 专门用于禁用浏览器默认右键菜单 |
需要为body设置高度