摘要:同样还是用上面冒泡例子,则事件的传播顺序则是特别说明之前不支持事件捕获,,,,,目前支持良好。取决于指定事件处理程序的方法。
第一次在segmentfault写文章,希望通过这种方式来巩固所学的知识,也欢迎童鞋们指正其中有不对和错误的地方。^+^
事件流
事件流:页面中接收事件的顺序,即当一个事件发生时,该事件的传播过程便叫做事件流
事件流的种类事件冒泡
事件由最具体的元素开始逐级向上传播至较为不具体的节点(文档)
点我
当我们点击id为box的div时,该点击事件传播顺序如下
div --> body --> html -->document
特别说明:IE5.5及更早的版本将绕过html节点直接到document,IE9,Firefox,chrome和safari将冒泡到window对象
事件捕获
事件捕获和事件冒泡似乎截然相反,由不太具体的节点先接收到事件 -->再到最具体的节点。同样还是用上面冒泡例子,则事件的传播顺序则是:
document --> html -->body -->div
特别说明:ie8之前不支持事件捕获,IE9,safari,chrome,opera,firefox目前支持良好。并且这些浏览器不是从document开始捕获,而是从window对象开始。
DOM事件流阶段捕获阶段
目标阶段
冒泡阶段
以上面的代码为例子,由图可以很清晰地看出首先发生的是事件捕获-->实际的目标接收事件-->事件冒泡
特别说明:在DOM事件流中,实际的目标不会在捕获阶段接收到事件,即捕获阶段到body就停止,"下一阶段"是目标阶段,该阶段可以看成是事件冒泡的一部分,最终事件又被传播会document。
BUT :我们的各大浏览器总是不喜欢按照规范来,IE9,Safari,chrome,firefox及其更高的版本中都会在捕获阶段出发事件对象上的事件,最后导致有两个机会在目标对象上操作事件。
事件处理程序
事件:用户或者浏览器自身执行的某个动作,比如load,click,mousemove等
事件处理程序:相应某个事件的函数叫做事件处理函数(也叫做事件侦听器)
1 html事件处理程序:某个元素支持的某个事件可以用与事件处理程序同名的html特性来指定,该特性的值是能够执行的javascript代码。
/* 当点击该按钮的时候,浏览器会弹出"我被点击了"; */
当然也可以给onclick赋值页面中其他地方定义的脚本
优点:简单明了,省去获取元素等一系列前提操作
缺点:html代码与js代码高度耦合,不符合分离原则
2 DOM0级别事件处理函数:使用 element.on[eventname]=fn的方式给元素添加事件
3 DOM2级事件处理程序:DOM2级添加了addEventListener(添加事件处理程序)和removeEventListener(移除事件处理程序)
添加事件处理函数
移除事件处理函数:如果事件处理函数是有名函数,则可以通过名字来移除,匿名函数无法移除。
4IE事件处理程序:ie实现了与dom类似的两个方法,attachEvent(添加),detachEvent(删除)
添加事件处理函数
删除事件处理函数
事件函数封装
绑定 为了解决attachEvent的this指向问题,并且可以通过有名称的函数来解除事件绑定,现在处理如下
// function bind(obj,eventName,fn){ var _fn=fn; fn=function(){ _fn.call(obj);//改变this指向 }; if(obj.addEventListener){ obj.addEventListener(eventName,fn,false); }else{ obj.attachEvent("on"+eventName,fn); } return fn;//用于事件解除 }
解除
function unbind(obj,eventName,fn){ if(obj.removeEventListener){ obj.removeEventListener(eventName,fn); }else{ obj.detachEvent("on"+eventName,fn); } }
使用方式
//给input添加和移除事件 //添加 function show( ){ alert(this); } function show2( ){ alert(this.id); } var removeFn=bind("box","click",show);//需要移除的事件处理程序,不是原程序名称show bind("box","click",show2); unbind("box","click",removeFn); //最后只会弹出 box事件对象
DOM中的事件对象当触发DOM上面的某个事件的时候,会产生一个事件对象event,这个对象中包含着所有与事件对象有关的信息。例如该事件类型,导致事件的元素等
DOM中的事件对象:兼容DOM的浏览器会将event对象传入到事件处理程序中,无论指定事件处理程序用什么方式(html方式,DOM0级方式,DOM2级方式)
//html方法 click var oBox=document.getElementById("box"); //DOM0级别方法 click oBox.onclick=function(ev){ console.log(ev.type);//click } ///DOM2级别方法 click oBox.addEventListener("click",function(ev){ console.log(ev.type);//click })
总的来说event对象包含与创建他的特定事件有关的属性和方法,但是触发的事件类型不同,则可用的属性和方法也不一样。但是都会包含以下成员
属性/方法 | 类型 | 读/写 | 说明 | |
---|---|---|---|---|
currentTarget | element | 只读 | 事件处理程序当前正在处理程序的那个元素,我的理解是事件的直接绑定者 | |
target | element | 只读 | 事件的目标 | |
cancelable | boolean | 只读 | 表示是否可以取消事件的默认行为 | |
preventDefault() | function | 只读 | 取消事件的默认行为 ,前提是cancelable为true | |
bubbles | boolean | 只读 | 表明事件是否可以冒泡 | |
stopPropagation() | function | 只读 | 取消事件的进一步冒泡或者捕获,前提是bubbles为true | |
type | boolean | 只读 | 事件类型 | |
view | abstractView | 只读 | 与事件关联的抽象视图,等同于发生事件的window对象 | |
detail | integer | 只读 | 与事件相关的细节信息 | |
eventPhase | integer | 只读 | 调用事件处理程序的阶段,1::捕获,2:“处于目标”,3:冒泡 | |
trusted | boolean | 只读 | 为true表示事件是由浏览器生成的,为false表示事件是由开发人员通过js生成的。(DOM3) | |
stopImmediatePropagation() | function | 只读 | 取消事件的进一步捕获或者冒泡,同时阻止任何事件处理程序被调用(DOM3) |
特别说明:只有在事件处理程序被执行的期间,event对象才会存在,一旦事件处理程序执行完成,其就会被销毁。
IE中的事件对象与访问DOM中的事件对象不同,要访问IE中的event对象有几种不同的方式。取决于指定事件处理程序的方法。
html event
函数参数
window.event
同样IE中的event对象也包含着与创建他的事件相关的属性和方法,其中很多的属性和方法都有对应的或者是相关的DOM属性和方法。当然也会事件的不同,其属性和方法也会有所不同,但是都会包含下表内容
属性/方法 | 类型 | 读/写 | 说明 | |
---|---|---|---|---|
srcElement | element | 只读 | 事件的目标(与DOM中的target属性相同) | |
type | string | 只读 | 事件的类型 | |
cancelBubble | boolean | 只读 | 默认为false,设置为true表示取消冒泡(与stopPropagation()作用相同) | |
returnValue | boolean | 只读 | 默认为true,设置为false就可以取消默认行为(与preventDefault()作用相同) |
我们为eventUtil添加几个方法,以此来达到有关event对象的常用的跨浏览器的使用目标
getEvent() 获取事件对象
getTarget()获取事件源
stopPropagation() 取消冒泡
preventDefault() 阻止默认行为
var eventUtil={ getEvent:function(ev){ return ev || window.event;//获取事件对象 }, getTarget:function(ev){ return ev.target || ev.srcElement;//获取事件源 }, stopPropagation:function(ev){//阻止冒泡 if(ev.stopPropagation){ ev.stopPropagation(); }else{ ev.cancelBubble=true; } }, preventDefault:function(ev){//阻止默认行为 if(ev.preventDefault){ ev.preventDefault(); }else{ ev.returnValue=true; } } }常见应用之事件委托
说明:需要给页面中成百上千个li绑定一个事件并且输出当前元素的innerHTML
常见做法
这种方式通过遍历DOM节点的方式添加事件处理程序有诸多缺点,比如性能大大减低,新添加的li不具备click事件等。
利用事件委托(冒泡原理)
var oUl//假设oUl是li的父节点 oUL.onclick=fuction(ev){ var ev=eventUtil.getEvent(ev); var target=eventUtil.getTarget(ev); console.log(target.innerHTML); }
利用事件委托可以大大地提高性能,后面随时添加的元素都可以拥有这个点击事件等
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/86046.html
摘要:取消事件的默认行为。阻止事件的派发包括了捕获和冒泡阻止同一个事件的其他监听函数被调用。 事件模型 DOM0 级事件模型 -没有事件流,这种方式兼容所有浏览器 // 方式一 将事件直接通过属性绑定在元素上 / 方式二 获取到页面元素后,通过 onclick 等事件,将触发的方法指定为元素的事件 var btn = document.getElementById(btn) btn....
摘要:缓冲模块起初就是为浏览器而设计的,所以能很好的处理编码的字符串,但不能很好的处理二进制数据。有如下三个主要的流标准输入标准输出标准错误可读流如果说,缓冲区是处理原始数据的方式的话,那么流通常是移动数据的方式。该方法让可读流继续触发事件。 缓冲(buffer)模块 js起初就是为浏览器而设计的,所以能很好的处理unicode编码的字符串,但不能很好的处理二进制数据。这是Node.js的...
阅读 2448·2021-10-08 10:17
阅读 1823·2021-09-06 15:02
阅读 2538·2019-08-29 17:30
阅读 2663·2019-08-29 13:24
阅读 1521·2019-08-29 11:12
阅读 3337·2019-08-28 17:52
阅读 666·2019-08-26 11:30
阅读 3575·2019-08-26 11:01