前言:撸完CSS-DOM紧接着来撸DOM事件,事件总结完成后我要开始总结动画,而后用纯JS实现一个轮播图,前路漫漫,还有各类框架等着我~~~
本篇主要内容有:事件流 事件处理程序 跨浏览器事件处理程序javascript
--------------------? 分割线---------------------html
事件冒泡:事件开始时由最具体的元素(文档嵌套层次最深的节点)接收,而后逐级向上传播到较为不具体的节点。
事件捕获:不太具体的节点应该更早接收到事件,最具体的节点应该最后接收到事件。java
在W3C规范中:分三步(一、事件捕获;二、事件触发;三、事件冒泡);
在IE中:分两步(一、事件冒泡;二、事件触发)
在网景(Netscape):分两步(一、事件捕获;二、事件触发)编程
这个在《DOM编程艺术》中初步实现的图片库的总结(一)就有了运用,它的js代码嵌套在HTML中,如:想要实如今点击按钮时显示一个警告框,则能够这么写:segmentfault
<input type="button" value="狠狠的点我" onclick="alert('clicked')"/>
缺点:
1.代码例子中的alert能够换成本身定义的函数,假如用户在页面加载后还没开始解析这个函数时就单击了按钮,这个时候就会引起错误,这时能够将事件处理程序封装在try-catch块中,上面的代码能够改成:浏览器
<input type="button" value="狠狠的点我" onclick="try{showsomething();}catch(ex){}"/>
2.HTML和js代码耦合性太强,若是要更换事件处理程序,就要改动两个地方。框架
每一个元素(包括window和document)都有本身的事件处理程序属性,例如onclick,将这种属性值设置为一个函数,就能够指定事件处理程序,以下方代码:函数
//假若有一个按钮,先获取这个按钮元素 var btn = document.getElementById("myBtn"); btn.onclick = function(){ alert("你点我干啥!!!"); };
注意:以上代码在运行以前不会指定事件处理程序,换句话说就是若是这些代码插入在html文档中的最后,位于按钮以后,body标签以前,那么在文档解析这个函数以前,点击按钮时无效的。动画
优势:简单,具备跨浏览器的优点this
特色:使用DOM 0级方法指定事件处理程序被认为是元素的方法,所以这个时候事件处理是在元素的做用域中进行运行,程序中的this指向当前元素。 来看下面一段代码:
var btn = document.getElementById("mybtn"); btn.onclick = function(){ alert(this.id); //this表明当前执行操做的元素btn,也就是id为mybtn的按钮 }
以上不只仅能够访问元素的id属性,元素的任何属性和方法均可以经过this访问。以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。
DOM 2级事件定义了两个方法,分别用于处理指定和删除事件处理程序的操做:addEventListener()
和removeEventListener()
,
他们都接收三个参数:要处理的事件名、做为事件处理程序的函数、一个布尔值。
布尔值若是是true表示在捕获阶段调用事件处理程序,若是是false表示在冒泡阶段调用事件处理程序。
添加事件操做
以下代码:
var btn = document.getElementById("myBtn"); btn.addEventListener("click",function(){ alert(this.id); },false); btn.addEventListener("click",function(){ alert("你点我干啥!!!"); },false);
以上代码为一个按钮添加了一个onclick事件处理程序,注意里面参数传递的是"click"
,这个是跟DOM中的事件类型有关,后续再说。~~~
而且使用DOM 2级方法添加事件处理程序的好处是,能够添加多个事件处理程序,上面例子中首先会显示元素id,而后显示"你点我干啥!!!"。
删除事件操做
经过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除,移除时传入的参数与添加程序时使用的参数相同。这也就意味着经过addEventListener()添加的匿名函数将没法移除。如上面的例子,我增长如下代码将没法移除事件:
btn.removeEventListener("click",function(){ alert(this.id); },false);
解决办法是,将上面的匿名函数赋值给一个变量,而后adddEventListener和 removeEventListener
传参数时传入这个变量就能够了。
重写这个函数以下:
var btn = document.getElementById("myBtn"); var handler = function(){ alert(this.id); }; btn.addEventListener("click",handler,false); btn.addEventListener("click",handler,false);
----------------- 珍爱生命,远离IE ------------------
IE也实现了DOM中的相似的两个方法:attachEvent() 和detachEvent(),这两个方法接受相同的两个参数,事件处理程序名称与事件处理程序函数。
以下代码:
var btn = document.getElementById("mybtn"); btn.attachEvent("onclick",function(){ //你没看错,用的“onclick”!!! alert("你又点我了!!!"); });
注意:
1.attachEvent()的第一个参数时“onclick”
2.使用attachEvent(),事件处理程序会在全局做用域中进行,所以this===window
3.添加多个事件时,事件处理程序不是以添加它们的顺序执行,而是以相反的顺序被触发。
4.使用detachEvent()来移除时,匿名函数一样不能移除,所以须要传递给函数相同的引用。
那么重点来了,能够封装一个对象解决跨浏览器进行事件处理,给这个对象起名叫:EventUtil,它有两个方法,分别进行事件添加和移除。
且看下面代码:
var EventUtil = { //@handler是装载匿名函数的引用变量,里面装载的是具体要执行的函数逻辑 //@element是目标元素 //type表明的是DOM 2级的事件类型,所以在用IE或者DOM 0级前面要加“on” addHandler: function (element, type, handler) { if (element.addEventListener) { element.addEventListener(type, handler, false); } else if (element.attachEvent) { element.attachEvent("on" + type, handler); } else { elemet["on" + type] = handler; //若是上面两种都不行,就使用DOM 0级方法处理,直接在元素上添加onclick事件 } }, removeHandler: function (element, type, handler) { if (element.removeEventListener) { element.removeEventListener(type, handler, false); } else if (element.detachEvent) { element.detachEvent("on" + type, handler); } else { element["on" + type] = null; ////若是上面两种都不行,就使用DOM 0级方法处理,直接赋值为null取消事件 } } };
定义好了,怎么使用呢?看下面~~~
var btn = document.getElementById("myBtn"); var handler = function(){ alert("你又点我了!!!"); }; //添加事件 EventUtil.addHandler(btn,"click",handler); //移除事件 EventUtil.removeHandler(btn,"click",handler);
以上代码并无考虑IE中的做用域问题,而且DOM 0级只支持一个事件处理程序,但也不是什么问题,现在只卖早餐的饭店很少了~~~
此次没有源代码,以上~