事件
注册事件
注册事件:给元素添加事件
注册事件的两种方式:
1.传统注册方式。 element.onclick = 事件处理函数。特点:事件唯一性,同一个元素的同一个事件只能注册一个,如果注册多个,后面的会覆盖前面的
2. 坚挺注册方式。addEventListener(), 是一个方法,IE9+支持,IE9之前的IE可以用attachEvent()。特点:同一个元素同一种事件可以注册多个,按注册顺序依次执行
监听注册事件
- element.addEventListener(type , listener[, useCapture]) IE9+支持
type: 事件类型 click mouseover 等,注意没有on,是一个字符串
listener:事件处理函数,事件发生时调用
useCapture:可选参数,布尔类型,默认false - element.attachEvent(eventNameWithOn , callback) IE9以前的支持
eventNameWithOn:事件类型字符串 onclick onmouseover ,注意有on
callback:回调函数,事件处理函数,事件发生时调用 - 事件监听兼容性解决方案,自定义一个注册事件的函数
function addEventLisener(element, type, fn) {
// 判断当前浏览器是否支持addEventLisner
if (element.addEventLisner) {
element.addEventLisner(type, fn);
}else if (element.attachEvent) { // 判断是否支持attachEvent
element.attachEvent('on' + type,fn);
}else {
// 相当于element.onclick
element.['on' + type] = fn;
}
}
删除事件
- 传统方式:element.onclick = null
- 监听方式:
element.removeEventListener(type, listener[, useCapture])
element.detachEvent(eventNameWithOn, callback) - 兼容性解决方法:
function removeEventListener(element, type, fn) {
if (element.removeEventLisner){
element.removeEventLisner(type, fn);
}else if(element.detachEvent) {
element.detachEvent('on' + type, fn);
}else {
element['on'+ type] = null;
}
}
DOM事件流
html页面中元素有嵌套,一个盒子包着一个盒子,比如点击了div,同时也点击了body,html,doucument
- 事件冒泡:从内向外(从子向父)依次触发事件
- 事件捕获:从外向里(从父向子)依次触发事件
DOM事件流:事件发生时会在元素节点之间按照特定顺序传播,这个传播过程即DOM事件流
DOM事件流会经历3个阶段:
- 事件捕获阶段,从外向里
- 当前目标阶段
- 事件冒泡阶段,从里向外
onclick 和 attachEvent 只能在事件冒泡阶段触发,addEventListener(type, fn[,useCapture])可选参数useCapture默认为false,在事件冒泡阶段触发,如果为ture,就在事件捕获阶段触发
注意:实际开发中很少用事件捕获,基本只关注事件冒泡
有些事件没有冒泡:onfocus,onblur,onmouseenter,onmouseleave
事件对象
元素触发事件时会把相关的信息保存在事件对象中,比如触发事件的对象,鼠标事件中鼠标的点击位置,键盘事件中键盘的哪个键等。
事件对象的使用
事件触发时就会产生事件对象,并且系统将它作为实参传递给事件处理函数,所以,需要在事件处理函数中声明一个形参来接收事件对象
function fn(event) {
// event 用来接收事件对象 也常写成e 或者 evt
console.log(event);
}
element.addEventListener(type, fn, false);
事件对象的兼容性处理
事件对象本身有兼容性问题,IE9+ 会在事件触发时将事件对象以实参的形式传递给事件处理函数,但IE9以前的浏览器不会传递实参,需要通过window.event 获取事件对象
事件对象的兼容性处理方法:
// 事件处理函数
function fn (e) {
// 如果e接收到事件对象就是e,否则就是window.event
e = e || window.event;
}
事件对象常用的属性和方法
- e.target:该属性保存触发事件的对象 标准
e.srcElement: 非标准 IE678支持
注意:e.target和this的区别:this指向绑定该事件的对象,e.target指向触发该事件的对象。通常情况下二者内容是相同的,但在事件冒泡时,二者可能不同。
// 比如 ul里面包含3个li
var ul = document.querySelector('ul');
// 给ul注册点击事件
ul.addEventListener('click', fn, false);
function fn(e) {
// 点击li触发事件 事件冒泡 li—>ul 触发该事件的是li,但绑定该事件的的ul
console.log(e.target); // li
console.log(this); // ul
// 注意了解e.currentTarget属性 和 this 很相似 非标准 IE9+支持
console.log(e.currentTarget); // ul
}
- e.type:事件类型,click,mouseover 不带on
- e.preventDefault() 方法:阻止元素默认事件发生,比如阻止链接跳转,标准
e.returnValue 属性,设置为false阻止默认事件发生,非标准,ie678使用
// 阻止链接跳转
var a = document.querySelector('a');
a.addEventListener('click', function(e){
e.preventDefault()
});
// 传统注册方式
a.onclick = function(e) {
e.preventDefault(); // 1. 普通浏览器
e.returnValue = false; // 2. ie678
return false; // 3. 这种方式只能在传统注册方式中使用
}
- e.stopPropagation():阻止事件冒泡 标准
window.event.cancelBubble : ie678使用,设置为true阻止事件冒泡,非标准
事件委托
不给子元素注册事件,给父元素注册事件,把处理代码放在父元素的事件处理函数中。利用了事件冒泡。
比如ul里面包含6个li,给每一个li注册事件很麻烦,于是不给li注册事件,只给ul注册事件,点击li时发生事件冒泡,触发ul的事件,在ul的事件处理函数中利用e.target(li)对li进行处理。
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e){
var li = e.target;
li.style.backgroundColor = 'red';
});
常用的鼠标事件补充
contextmenu : 鼠标右键弹出菜单
selectstart:选中文字
常用于取消右键菜单和禁止文字选中
// 取消右键点击弹出菜单
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
});
// 禁止文字被选中
document.addEventListener('selectstart', function(e){
e.preventDefault();
})
鼠标事件对象
event事件对象保存事件发生的相关信息,主要用到的是鼠标事件对象mouseEvent和键盘事件对象keyboardEvent
鼠标事件对象常用属性
- e.clientX , e.clientY 相对于浏览器视口的坐标
- e.pageX , e.pageY 相对于文档页面的坐标
- e.screenX , e.screenY 相对于整个屏幕的坐标
常用的键盘事件
- keydown 某个键按下时触发事件
- keypress 某个键按下时触发,不包括ctrl shift 箭头等功能键
- keyup 某个键弹起时触发
三个事件的触发顺序:keydown—keypress—keyup
注意:keydown和keyup不区分大小写,keypress区分大小写
键盘事件对象
键盘事件对象常用的属性:e.keyCode 返回触发事件的按键的ASCII码值