事件

什么是事件

事件分为两部分:
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/onmouseoutonmouseenter/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
loadDOM2级事件绑定就可以执行多次

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 8,862评论 1 11
  • 事件流 JavaScript与HTML之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互...
    DHFE阅读 4,251评论 0 3
  • 事件流分为两种,捕获事件流和冒泡时间流 捕获事件流:从根节点出发开始执行,一直往子节点查找执行,直到查到到根节点。...
    路上灵魂的自由者阅读 3,021评论 0 0
  • 前言 本文主要介绍: DOM事件级别 DOM事件流 DOM事件模型 事件代理 Event对象常见的方法和属性 一、...
    xyyojl阅读 5,010评论 0 3
  • js之事件机制 1、事件初探 1.1 js事件的概述 JavaScript事件:JavaScript是基于事件驱动...
    道无虚阅读 7,038评论 0 2