抽空学习了下javascript和jquery的事件设计,收获颇大,总结此贴,和大家分享。
(一)事件绑定的几种方式
javascript给DOM绑定事件处理函数总的来说有2种方式:在html文档中绑定、在js代码中绑定。下面的方式1、方式2属于在html中绑定事件,方式3、方式4和方式5属于在js代码中绑定事件,其中方法5是最推荐的做法。
方式1:
HTML的DOM元素支持onclick、onblur等以on开头属性,我们可以直接在这些属性值中编写javascript代码。当点击div的时候,下面的代码会弹出div的ID:
<div></div>
这种做法很显然不好,因为代码都是放在字符串里的,不能格式化和排版,当代码很多的时候很难看懂。这里有一点值得说明:onclick属性中的this代表的是当前被点击的DOM对象,所以我们可以通过this.id获取DOM元素的id属性值。
方式2:
当代码比较多的时候,我们可以在onclick等属性中指定函数名。
<script> function buttonHandler(thisDom) { alert(this.id);//undefined alert(thisDom.id);//outestA return false; } </script> <div></div>
跟上面的做法相比,这种做法略好一些。值得一提的是:事件处理函数中的this代表的是window对象,所以我们在onclick属性值中,通过this将dom对象作为参数传递。
方式3:在JS代码中通过dom元素的onclick等属性
var dom = document.getElementById("outestA"); dom.onclick = function(){alert("1=" + this.id);}; dom.onclick = function(){alert("2=" + this.id);};
这种做法this代表当前的DOM对象。还有一点:这种做法只能绑定一个事件处理函数,后面的会覆盖前面的。
方式4:IE下使用attachEvent/detachEvent函数进行事件绑定和取消。
attachEvent/detachEvent兼容性不好,IE6~IE11都支持该函数,但是FF和Chrome浏览器都不支持该方法。而且attachEvent/detachEvent不是W3C标准的做法,所以不推荐使用。在IE浏览器下,attachEvent有以下特点。
a) 事件处理函数中this代表的是window对象,不是dom对象。
var dom = document.getElementById("outestA"); dom.attachEvent('onclick',a); function a() { alert(this.id);//undefined }
b) 同一个事件处理函数只能绑定一次。
var dom = document.getElementById("outestA"); dom.attachEvent('onclick',a); dom.attachEvent('onclick',a); function a() { alert(this.id); }
虽然使用attachEvent绑定了2次,但是函数a只会调用一次。
c)不同的函数对象,可以重复绑定,不会覆盖。
var dom = document.getElementById("outestA");
dom.attachEvent('onclick',function(){alert(1);});
dom.attachEvent('onclick',function(){alert(1);}); // 当outestA的click事件发生时,会弹出2个对话框
匿名函数和匿名函数是互相不相同的,即使代码完全一样。所以如果我们想用detachEvent取消attachEvent绑定的事件处理函数,那么绑定事件的时候不能使用匿名函数,必须要将事件处事函数单独写成一个函数,否则无法取消。
方式5:使用W3C标准的addEventListener和removeEventListener。
这2个函数是W3C标准规定的,FF和Chrome浏览器都支持,IE6/IE7/IE8都不支持这2个函数。不过从IE9开始就支持了这2个标准的API。
// type:事件类型,不含"on",比如"click"、"mouseover"、"keydown"; // 而attachEvent的事件名称,含含"on",比如"onclick"、"onmouseover"、"onkeydown"; // listener:事件处理函数 // useCapture是事件冒泡,还是事件捕获,默认false,代表事件冒泡类型 addEventListener(type, listener, useCapture);
a) 事件处理函数中this代表的是dom对象,不是window,这个特性与attachEvent不同。
var dom = document.getElementById("outestA"); dom.addEventListener('click', a, false); function a() { alert(this.id);//outestA }
b) 同一个事件处理函数可以绑定2次,一次用于事件捕获,一次用于事件冒泡。
var dom = document.getElementById("outestA"); dom.addEventListener('click', a, false); dom.addEventListener('click', a, true); function a() { alert(this.id);//outestA }// 当点击outestA的时候,函数a会调用2次
如果绑定的是同一个事件处理函数,并且都是事件冒泡类型或者事件捕获类型,那么只能绑定一次。
var dom = document.getElementById("outestA"); dom.addEventListener('click', a, false); dom.addEventListener('click', a, false); function a() { alert(this.id);//outestA } // 当点击outestA的时候,函数a只会调用1次
c) 不同的事件处理函数可以重复绑定,这个特性与attachEvent一致。
(二)事件处理函数的执行顺序