事件
事件三要素
- 事件源(谁):触发事件的元素
- 事件类型(什么事件): 例如 click 点击事件
- 事件处理程序(做什么):事件触发后要执行的代码(函数形式),事件处理函数
执行事件的步骤
- 获取事件源
- 注册事件
- 添加事件处理程序
注册事件
传统注册方式
button.onclick = function(){}
同一个元素同一个事件只能设置一个处理函数,后注册的会覆盖先注册的
监听注册方式
button.addEventListener('click',function(e){})
addEventListener 还有第三个参数,提供了更多选项:
- once:只执行一次。
- passive:承诺此事件监听不会调用preventDefault,这有助于性能。
- useCapture:是否捕获(否则冒泡)。
同一个元素可以注册多个处理函数,按注册顺序依次执行
删除事件
// 传统方式
button.onclick = null;
button.removeEventListener('click',fn);
DOM事件流
- 事件冒泡:事件开始时有最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程
- 事件捕获:由DOM最顶层节点开始,然后主机向下传播到最具体的元素接收的过程
DOM 事件流会经历3个阶段:
- 捕获阶段
- 当前目标阶段
- 冒泡阶段
addEventListener
的第三个参数如果是true表示在事件捕获阶段调用事件处理函数,反之则是在事件冒泡阶段调用
事件对象
事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象
在 IE6~8 中,浏览器不会给方法传递参数,如果需要的话,需要到 window.event 中获取查找
常见属性和方法
t通常情况下terget 和 this是一致的
但有一种情况不同,那就是在事件冒泡时(父子元素有相同事件,单击子元素,父元素的事件处理函数也会被触发执行),
这时候this指向的是父元素,因为它是绑定事件的元素对象,而target指向的是子元素,因为他是触发事件的那个具体元素对象。
阻止默认行为
a.onclick = function(e) {
// 普通浏览器 e.preventDefault(); 方法
e.preventDefault();
// 低版本浏览器 ie678 returnValue 属性
e.returnValue = false;
// 我们可以利用return false 也能阻止默认行为 没有兼容性问题
return false;
}
阻止冒泡
// 阻止事件继续向上传递给父组件
son.addEventListener('click', function(e) {
alert('son');
e.stopPropagation(); // stop 停止 Propagation 传播
window.event.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡
}, false);
事件委托
给父元素注册事件,利用事件冒泡,当子元素的事件触发,会冒泡到父元素,然后去控制相应的子元素
- 我们只操作了一次 DOM ,提高了程序的性能。
- 动态新创建的子元素,也拥有事件。
常见事件
鼠标事件
鼠标事件对象
键盘事件
键盘事件 | 触发条件 |
---|---|
onkeyup | 某个键盘按键被松开时触发 |
onkeydown | 某个键盘按键被按下时触发 |
onkeypress | 某个键盘按键被按下时触发,但是不识别功能键 |
键盘事件对象
- keyCode:返回该键的ASCII值
mouseenter 和mouseover的区别
当鼠标移动到元素上时就会触发mouseenter 事件,- mouseover 鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter 只会经过自身盒子触发,之所以这样,就是因为mouseenter不会冒泡,跟mouseenter搭配鼠标离开 mouseleave 同样不会冒泡
触屏事件
移动端浏览器兼容性较好,我们不需要考虑以前 JS 的兼容性问题,可以放心的使用原生 JS 书写效果,但是移动端也有自己独特的地方。比如触屏事件 touch(也称触摸事件),Android和 IOS 都有
常见的触屏事件
触屏事件 | 说明 |
---|---|
touchstart | 手指触摸到一个DOM元素时触发 |
touchmove | 手指在一个DOM元素上滑动时触发 |
touchend | 手指从一个DOM元素上移开时触发 |
触摸事件对象(TouchEvent)
触摸列表 | 说明 |
---|---|
touches | 正在触发屏幕的所有手指的一个列表 |
targetTouches | 正在触发当前DOM元素上的手指的一个列表 |
changedTouches | 手指状态发生了改变的列表,从无到有,从有到无的变化 |
click 延时解决方案
移动端 click 事件会有 300ms 的延时,原因是移动端屏幕双击会缩放(double tap to zoom) 页面
- 禁用缩放
<meta name="viewport" content="user-scalable=no">
- 利用touch事件封装事件解决300ms 延迟
- 当我们手指触摸屏幕,记录当前触摸时间
- 当我们手指离开屏幕, 用离开的时间减去触摸的时间
- 如果时间小于150ms,并且没有滑动过屏幕, 那么我们就定义为点击
- fastclick 插件
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
自定义事件
var evt = new Event("look", {"bubbles":true, "cancelable":false});
document.dispatchEvent(evt);
当自己封装组件时,自定义事件可以帮助进行解耦