JavaScript与HTML之间的交互式通过事件实现的
1、事件流:事件流描述的是从页面中接收事件的顺序。
2、两种不同的事件流概念
1)事件捕获流 2) 事件冒泡流
IE的事件流叫做事件冒泡,即事件是从最具体的元素接收,逐级向上传递到较为不具体的节点(文档)
div -->body-->html-->document
所有现代浏览器都支持事件冒泡,但在具体实现上还是有一些差别 。
Netspace 提出的另一种事件流叫做事件捕获。不太具体的节点应该更早的接收到事件,最具体的节点最后接收到事件。
document-->html-->body-->div
IE9 、Safari、Chrome、Opera 和FireFix 目前也都支持。
3、事件冒泡的应用
事件代理
可以不在子节点上一一绑定事件,而在父节点上统一处理。
HTML事件处理程序
<input type="button" value="click me" onclick="alert('clicked')" >
2. DOM0级事件处理程序
<input type="button" value="clice me" id="btn"> var btn=document.getElementById("btn"); btn.onclick=function(){ alert("clicked"); }
btn.onclick=null; //删除事件处理程序
3.DOM2级事件处理程序
DOM2级事件中定义了两个方法,用于处理指定和删除处理事件处理程序的操作 addEventListener() 和 removeEventListener();
IE9+ 、Chrome、Firefox 、Safari和Opera都支持DOM2级事件处理程序。
var btn=document.getElementById("btn"); btn.addEventListener("click",function(){ },false) // 这两个方法都接受3个参数,要处理的事件名,作为事件处理程序的函数和一个布尔值,布尔值为true,表示在捕获阶段调用事件处理程序,如果是false 表示在冒泡阶段调用事件处理程序。 IE 事件处理程序 attachEvent() 和detachEvent() var btn=document.getElementById("btn"); btn.attachEvent("onclick",function(){ });
跨浏览器的事件处理程序
视情况分别使用DOM0级、DOM2级或者IE方法来添加事件
var EventUtil={ addHandler:function(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false){ } }else if(element.attachEvent){ element.attachEvent("on"+type,handler) }else{ element["on"+type]=handler } }, removeHandler:function(element,type,handler){ if(element.removeEventListener){ element.removeEvementListener(type,handler,false) }else if(element.detachEvent){ element.detach("on"+type,handler); }else{ element["on"+type]=null } } } var btn=document.getElementById("btn"); var handler=function(){ alert("clicked"); }; EventUtil.addHandler(btn,"click",handler); ///// EventUtil.removeHandler(btn,"click",hander)
大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样就可以最大限度的兼容各种浏览器(IE8及更早版本只支持事件冒泡)
在IE中使用attachEvent()与使用DOM0级方法的主要区别在于事件处理程序的作用域。在使用DOM0级方法的情况下,事件处理程序会在其所属元素的作用域内运行;在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此this等于window
在编写跨浏览器的代码时,一定要牢记这一点
事件对象
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件相关的信息。
event对象包含与创建它的特定事件有关的属性和方法。触发的事件类型不一样,可用的属性和方法也 不一样。不过,所有事件都会有下表列出的成员。
属性/方法 | 类型 | 读/写 | 说明 |
bubbles | Boolean | 只读 | 表明事件是否冒泡 |
cancelable | Boolean | 只读 | 表明是否可以取消事件的默认行为 |
currenttarget | Element | 只读 | 其事件处理程序当前正在处理事件的那个元素 |
defaultprevented | Boolean | 只读 | 为true表示已经调用了preventFefault()(DOM3级事件中新增) |
detail | Integer | 只读 | 与事件相关的细节信息 |
eventPhase | Integer | 只读 | 调用事件处理程序的阶段:1表示捕获阶段,2表示“处于目标”,3表示冒泡阶段 |
preventDefault() | Function | 只读 | 取消事件的默认行为。如果cancelable为true,则可以使用这个方法 |
stopImmediatePropagation() | Function | 只读 | 取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用(DOM3级事件中新增) |
stopPropagation() | Function() | 只读 |
取消事件的进一步冒泡,如果cancelable为true则可以使用这个方法 |
在事件处理程序内部,对象this始终等于currentTarget的值,而target则只包含事件的实际目标。如果直接将事件处理程序指定给了目标元素,则this、currentTarget和target包含相同的值。 比如下面的例子
<input type="button" value="这是一个按钮" id="myBtn"> <script> var btn=document.getElementById("myBtn"); btn.onclick=function(event){ alert(event.currentTarget===this); //true alert(event.target===this); //true } </script>
这个例子检测了currentTarget和target与this的值。由于clic事件的目标是按钮,因此这三个值是相等的。如果事件 处理程序存在于按钮的父节点中(例如document.body),那么这些值是不同的。
document.body.onclick=function(event){ alert(event.currentTarget===document.body);// true alert(this===document.body); alert(event.target===document.getElementById("myBtn"));// true }
当单击这个例子中的按钮时,this和currentTarget都等于document.body,因为事件处理程序是注册到这个元素上的。然而,target元素却等于按钮元素,因为他是click事件真正的目标。由于按钮上并没有注册事件处理程序,结果click事件就冒泡到了document.body,在那里事件才能得到处理。
原文链接:http://blog.leanote.com/post/jiang/%E4%BA%8B%E4%BB%B6
文章评论