什么是事件
事件分为两部分:
1)行为本身:浏览器赋予的行为(本来就存在的):onclick、onmouseover(onmouseenter)、onmouseout(onmouseleave)、onmousemove、onmousedown、onmouseup、onmousewheel(鼠标滚轮滚动)、onscroll、onresize(window.onresize浏览器窗口大小改变事件)、onload、onunload(浏览器关闭的时候)、onfocus(文本框获取焦点)、onblur(文本框失去焦点)、onkeydown、onkeyup(键盘的按下和抬起)
2)事件绑定:给元素的某一个行为绑定方法,两种方式:DOM0级事件绑定(例如element.onclick = function(){})
和DOM2级事件绑定(例如element.addEventListener("click", function(){}, false))
// 当点击元素的时候这个方法执行
// 这种方式是定义在当前元素的私有属性上的
// DOM0级事件绑定
element.onclick = function(){}
// same as
// 这种方式是定义在当前元素的所属EventTarget类的原型上的
// DOM2级事件绑定
element.addEventListener("click", function(){}, false);
绑定的时候是把匿名函数当做一个值赋值给元素的行为,当触发行为的时候,这个绑定的方法才会执行,此时浏览器默认地给这个方法传递了一个参数值,以点击行为为例,
MouseEvent
鼠标事件对象。
1)它是一个对象数据类型值,里面包含很多方法和属性,都是用来记录当前鼠标相关信息的
2)MouseEvent--UIEvent--Event--Object
3)MouseEvent
记录的是页面中唯一一个鼠标每次触发时候的相关信息,和到底是哪个元素上触发的没有关系
事件对象MouseEvent的兼容问题
1)事件对象本身的获取存在兼容问题,标准浏览器中是浏览器默认传递,只需我们定义形参
e
即可获取;IE6-8下浏览器不会给方法传递这个参数,若要使用,则需通过window.event
获取查找。兼容写法:
oDiv.onclick = function(e){
e = e || window.event;
}
e.clientX/e.clientY
:鼠标触发点距离当前屏幕
左上角的x/y轴的坐标
e.pageX/e.pageY
:鼠标触发点距离body
左上角的x/y轴的坐标,IE6-8没有这个属性,若要计算,则需要e.clientX加上滚动条卷去的宽度/e.clientY加上滚动条卷去的高度
oDiv.onclick = function(e){
e.pageX = e.pageX || (e.clientX + ( document.documentElement.scrollLeft || document.body.scrollLeft));
e.pageY = e.pageY || (e.clientY + ( document.documentElement.scrollTop || document.body.scrollTop));
}
e.type
:存储的是鼠标触发的行为类型
e.target
:事件源,当前鼠标触发的是哪个元素,那么它存储的就是哪个元素。IE6-8下值为undefined
,使用e.srcElement
获取
oDiv.onclick = function(e){
e.target = e.target || e.srcElement;
}
e.preventDefault
:组织浏览器的默认行为,vue中直接在绑定事件时@event.prevent
即可
例如,其他元素的:hover在IE6下不兼容,需要在元素里面嵌套一个a标签来实现,这个时候点击当前元素不想让a标签跳转,就可以使用e.preventDefault
来阻止默认的跳转行为。IE6-8没有这个属性,使用e.returnValue=false
。
return false
也可以;直接在a标签中href="javascript:; href="javascript:void 0;" href="javascript:void 1;"
都可以
oDiv.onclick = function(e){
e.preventDefault ? e.preventDefault() : e.returnValue=false;
// same as
return false;
}
e.stopPropagation
:阻止事件冒泡传播,IE6-8不兼容用e.cancleBubble=true
oDiv.onclick = function(e){
e.stopPropagation? e.stopPropagation : e.cancleBubble=true;
}
e.keycode
:当前键盘上每个键对应的值
空格键(space):32
删除键:8
回车键(enter):13
回退键(delete):46
四个方向键:左37 上38 右39 下40
事件的默认传播机制
捕获阶段:从外向里依次查找元素
目标阶段:当前事件源本身
冒泡阶段:从内到外依次触发相关行为(最常用的就是冒泡阶段)
1、使用DOM0级事件
绑定给元素的某一个方法,都是在行为触发后的冒泡阶段执行方法的。
在冒泡阶段,不仅当前元素的行为被触发,他的所有父级元素的行为也会被触发,若父级元素也有绑定方法,这个方法也会执行
注意:
每个浏览器中的最顶层是不一样的,谷歌浏览器中可以传播到document,但IE中只能传播到html。
2、使用DOM2级事件
绑定给元素的某一个方法
addEventListener三个参数:
1.当前行为的类型(如click),2.给当前行为绑定的方法,3.控制在哪个阶段发生true:在捕获阶段;false:在冒泡阶段
onmouseover/onmouseout
和onmouseenter/onmouseleave
都是鼠标滑上滑下的效果,区别在于后两者默认阻止了事件冒泡。
事件委托
利用事件的冒泡传播机制(触发当前元素的某个行为,他父级所有元素的相关行为都会被触发),如果一个容器中有很多元素都要绑定点击事件,只需要给最外层容器绑定即可,通过事件源的区分来进行不同的操作
DOM0级和DOM2级事件绑定
DOM2
级事件绑定是让元素通过原型链一直找到EventTarget
这个内置类的原型上的addEventListener
方法实现的
1)DOM0
级事件绑定:只能给一个元素的某一个行为绑定一此方法,第二次绑定会把第一次的绑定覆盖
2)DOM0
中的行为类型用DOM2
一样可以绑定;而且DOM2
中还提供了一些DOM0
中没有的行为类型,如DOMContentLoaded
:当页面中的DOM结构(HTML结构加载完成)出发的行为
window.onload=function(){}
:当页面中的所有资源都加载完成(图片、HTML结构、音视频...)才会执行后面的函数;并且在一个页面中只能用一次,后面再写会把前面的覆盖掉。因为是用DOM0
级事件绑定的只能绑定一次
jQuery:$(document).ready(function(){})
当页面中的HTML结构加载完成就可以执行对应的函数;并且在一个页面中可以出现多次。用DOM2
级事件绑定的,绑定的行为就是DOM2
中新增加的DOMContentLoaded
load
用DOM2
级事件绑定就可以执行多次
window.addEventListener("load", function(){}, false);
window.addEventListener("load", function(){}, false);
// 两个不会冲突
3)在解除事件绑定的时候,
DOM0
级可以直接赋值为null,而DOM2级需要在绑定的时候使用具名函数,removeEventListener
来移除(行为本身,方法,哪个阶段发生三个参数必须都有),匿名函数不可以
4)只能给某个元素的同一个行为绑定多个不同的方法,如果方法相同,只能留一个,当行为触发,会按照绑定的先后顺序依次把绑定好的方法执行,执行的时候方法中的this是当前被绑定事件的元素本身
事件池
:用来存储当前行为绑定的方法的(浏览器自带的机制)
IE6-8浏览器中不支持addEventListener/removeEventListener
,实现DOM2
级事件绑定需要用attachEvent/detachEvent
,只有两个参数,不能控制函数在哪个阶段执行,默认只在冒泡阶段发生,行为参数需要添加on
,和DOM0
级事件很类似
box.attachEvent("onclick", function(){});
和标准浏览器事件池对比:
1)执行顺序是乱序,标准浏览器事件池中是按绑定顺序依次执行的
2)不能区分同一个绑定的方法,会重复执行
3)this不是当前绑定的元素,而是window
网友评论