事件的定义
事件:元素天生具备的行为方式(和写不写JS代码没有关系)【onclick不是事件,click才是事件,浏览器会把一些常用事件挂载到元素对象的私有属性上,让我们可以实现DOM0事件绑定】,当我们去操作元素的时候会触发元素的很多事件
事件绑定:给当前元素的某个事件绑定方法,目的是让当前元素某个事件被触发时,做出一些反应
事件绑定的两种方法
1.DOM0级事件绑定
curEle.οnclick=function(){};
2.DOM2级事件绑定
标准浏览器:curEle.addEventListener('click',function(){},false)
IE6-8:curEle.attachEvent('onclick',function(){})
DOM0事件
常用事件汇总
[PC端]
表单元素常用的事件
- blur:失去焦点
- focus:获取焦点
- change:内容改变
- select:被选中事件
键盘常用事件行为
- keydown:键盘按下
- keyup:键盘抬起
- keypress:键盘按下(中文输入法不能触发,英文状态下可以触发,因为文本被输入到文本框中)
鼠标常用事件行为
click:点击(不是单击)
dblclick:双击(300ms之内连续触发两次点击事件)
mouseover:鼠标滑过
mouseout:鼠标滑出
mouseenter: 鼠标进入
mouseleave: 鼠标离开
mousedown:鼠标按下(左键)
mouseup:鼠标左键抬起
mousewheel:鼠标滚轮滚动
其他常用事件行为‘
- load:加载成功
- error:加载失败
- scroll:
- resize:大小改变事件:window.onresize:浏览器窗口改变大小触发该事件
[移动端]
移动端键盘一般都是虚拟键盘,虽然存在keydown,keyup,但兼容不好,使用input事件代替
移动端没有鼠标,所以鼠标类事件在移动端兼容性非常差,mouse类事件基本无法使用
移动端大部分事件是靠手指完成的,所以它独有手指事件
- 单手指事件:touchstart touchmove touchend touchcancel
- 多手指事件:gesturestart gestuerchange gestuerend…..移动端还有很多事件是靠硬件完成的:手机传感器,陀螺仪,重力感应器等
移动端兼容click事件,它把click当做单击使用(会有300MS的延迟事件)
事件对象
对以下事件绑定的严谨版描述:基于DOM0级事件的绑定方式,给box的click事件绑定了一个方法。当手动触发click事件时,会把绑定的方法执行
box.οnclick=function(e){
arguments[0]===e;//=>e就是事件对象
e=e||window.event;(兼容版获取事件对象的写法)
};
当元素的某个事件行为被触发,不仅会把之前绑定的方法执行,还会给绑定的方法传递一个值(浏览器默认传递的),我们把传递的这个值称为事件对象:(标准浏览器)
- 这个值是个对象类型的值,里面存储了很多的属性和方法,
- 这些存储的值都是当前本次操作的基本信息,例如:鼠标位置,触发行为类型。。。。【只和本次操作有关,一个页面中只有一个事件对象】IE6-8下关于事件对象的机制
- 方法被触发执行时,浏览器并没有把事件对象当做值传递给函数;(e是undefined)
- IE6-8下的事件对象需要我们通过window.event来获取
鼠标事件对象(mouseevent)
clientX/clientY
:当前鼠标触发点距离当前窗口左上角
的X/Y坐标pageX/pageY
:当前鼠标触发点距离BODY左上角
的X/Y坐标(IE6-8中没有这两个属性)兼容处理
box.onckick=function(e){
if(typeof e==='undefined'){
e=window.event; //->处理e
//->pageX/pageY
e.pageX=e.clientX+(document.documentElement.scrollLeft||document.body.scrollLeft);
e.pageY=e.clientY+(document.documentElement.scrollTop||document.body.scrollTop);
//->target
e.target=e.srcElement;
//->preventDafault
e.preventDefault=function(){
e.returnValue=false;
};
//=>stopPropagation
e.stopPropagation=function(){
e.cancelBubble=true
}
}
}//该兼容比较完整,当处理一个简单兼容时可简单处理
· type:当前触发事件的类型
· target:事件源(当前鼠标操作的是那个元素)(IE6-8没有该属性,用srcElement这个属 性代表事件源)
· preventDefault:作用:阻止事件的默认行为;(IE6-8没有该方法,使用 returnValue=false 处理)
· stopPropagation:阻止事件的冒泡传播 [IE6-8不兼容,使用cancelBubble=true来处理]
键盘事件对象(keyboardEvent)
· code:当前按得键盘按键是哪一个 【IE6-8没有这个属性】key属性和code一样,储存形式 不一样
· keyCode:存储的是当前按键的码值(大部分按键都有自己的码值)
· which:和keyCode一样,也是当前按键的码值(which不兼容IE6-8)
这几个码值需要记住(删除:8 、 回车:13、 空格:32、 tab :9、)
手指事件对象(TouchEvent)
touches&&changedTouches&&targetTouches:存储的是当前屏幕上每一个手指操作的位置信息
- touches:只有手指在屏幕上我们才能获取相关信息,手指离开后,这样touchend事件中我们就无法通过touches获取手指信息
- changedTouches:手指在屏幕上时,和touches一样可以获得相关信息,手指离开后也可以记录手指离开屏幕一瞬间所在的位置信息(最常用的)
touchesEvent
type:'touchStart',
target:事件源,
touches:
0:{
clientX:xxx,
clientY:xxx,
pageX:xxx,
pageY:xxx,
.....
}
...
lentth:1
chan
DOM2事件绑定
//=>标准浏览器
oBox.addEventLister('click',function(e){
//this:obx
},false)
//false=>让事件在冒泡传播时执行
//true=>让事件在捕获阶段执行(非常少见)
//=>IE6-8浏览器
oBox.attachEvent('onclick',function(e){
//e:事件对象,不同于DOM0级事件,浏览器会默认将事件对象传递进来,与window.event的值相同,因此对于:pageX/pageY/target...等依旧存在兼容;
})
//=>绑定的方法都是在冒泡传播阶段执行
DOM0于DOM2事件绑定的区别
DOM0事件绑定的原理
· 给当前元素的某一私有属性(onXXX)赋值的过程;(之前属性默认值是null,如果我们 赋值了一个函数,就相当于绑定了一个方法)
· 当我们赋值成功(赋值一个函数),此时浏览器会把DOM元素和赋值的的函数建立关联, 以及建立DOM元素的行为监听,当某一行为被用户触发,浏览器会把赋值的函数执行;DOM0事件绑定的特点:
· 只有DOM元素天生拥有这个私有属性(onxxx事件私有属性),我们赋值的方法才叫事件 绑定,否则属于设置自定义属性
· 移除事件绑定的时候,我们只需要赋值为null;
· 在DOM0事件绑定中,只能给当前元素的某一个事件行为绑定一个方法,绑定多个方法, 最后一次的绑定的会替换前面绑定的
DOM2事件绑定的原理
· DOM2事件绑定使用的 addEventListener/attachEvent方法都是在eventTarget这个内置 类的原型上定义的,我们调用的时候,首先要通过原型链找到这个方法,然后执行完成事 件绑定的效果
· 浏览器会给当前元素的某个事件行为开辟一个事件池(事件队列)【浏览器有一个统一的 事件池,每个元素绑定的行为都放在这里,通过相关标志区分】,当我们通过 addEventListener/attachEvent进行事件绑定的时候,会把绑定的方法放在事件池中;
· 当元素的某一行为被触发,浏览器回到对应事件池中,把当前放在事件池的所有方法按序 依次执行特点
· 所有DOM0支持的行为,DOM2都可以用,DOM2还支持DOM0没有的事件行为(这样说 比较笼统)
(核心)【浏览器会把一些常用事件挂载到元素对象的私有属性上,让我们可以实现DOM0 事件绑定,DOM2:凡是浏览器给元素天生设置的事件在DOM2中都可以使用】
例如:onDOMContentLoaded(所有的DOM0和IE6-8的DOM2都不支持)onDOMContentLoaded//当前浏览器中的DOM结构加载完成,就会触发这个事件
· DOM2中可以给当前元素的某一事件行为绑定多个不同方法(因为绑定的所有方法都放在 事件池中);
· 事件的移除:事件类型、绑定的方法、传播阶段三个完全一致,才可以完成移除(因此在绑 定方法时,尽量不要用匿名函数,否则不好移除)
//=>ON:给当前元素的某个事件绑定某个方法
var on = function (curEle, type, fn) {
if (document.addEventListener) {
//=>标准浏览器
curEle.addEventListener(type, fn, false);
return;
}
//=>IE6~8
curEle.attachEvent('on' + type, fn);
};
//=>OFF:移除当前元素某个事件绑定的某个方法
var off = function (curEle, type, fn) {
if (document.removeEventListener) {
curEle.removeEventListener(type, fn, false);
return;
}
//=>IE6~8
curEle.detachEvent('on' + type, fn);
};
dom0 与 dom2 区别
dom0:同一个事件只会执行一次
dom2:同一个事件可以监听多次
事件的监听
1.作用:
如果是普通的事件绑定,相同事件类型,只能绑定一个事件处理函数
如果同一个类型,绑定多个事件处理函数,后绑定的事件会覆盖之前绑定的事件
2.语法:
标签对象.addEventListener(事件类型 , 事件处理函数)
第三个参数: true / false(默认值)
oDiv1.addEventListener('click' , function(){} , true)
3.事件的获取方式
冒泡 : 从子级开始,向父级执行
捕获: 从父级开始,向子级执行
浏览器默认都是冒泡的执行方式
可以通过 addEventListener 第三个参数来设定获取方式
默认值 false 是 冒泡方式 true是捕获方式
一般实际项目中,不定义第三个参数,就使用默认方式
低版本IE,只支持冒泡,不支持捕获,不会报错,只会按照冒泡的顺序执行
<div>123</div>
<script>
var oDiv = document.querySelector('div');
var fun4 = function(){
console.log('abc');
}
oDiv.addEventListener('click' , fun1);
oDiv.addEventListener('click' , fun2);
oDiv.addEventListener('click' , fun3);
oDiv.addEventListener('click' , fun4);
oDiv.addEventListener('click' , function(){console.log('别想删我')});
// 可以删除
oDiv.removeEventListener('click' , fun1);
oDiv.removeEventListener('click' , fun4);
// 不能删除
oDiv.removeEventListener('click' , function(){console.log('别想删我')});
function fun1(){
console.log(123);
}
function fun2(){
console.log(456);
}
function fun3(){
console.log(789);
}
//控制台结果:fun1 fun4 被删除 其他都执行
</script>