事件模塊的演變

作者: snandy  來源: 博客園  發布時間: 2011-04-12 10:40  閱讀: 2028 次  推薦: 0   原文鏈接   [收藏]  
 

  本篇開始將回顧下Javascript的事件機制。同時會從一個最小的函數開始寫到最后一個具有完整功能的,強大的事件模塊。為敘述方便將響應函數/回調函數/事件Listener/事件handler都稱為事件handler。

  先看看頁面中添加事件的幾種方式:

  1,直接將JS代碼寫在HTML上

 
<div onclick="alert(4);">Div1 Element</div>

  HTML Element元素自身就擁有了很多onXXX屬性,只需將JS代碼賦值給其就可以了。賦值給onXXX的字符串將作為響應函數的函數體(FunctionBody)。大概這是上世紀90年代的寫法,那時候直接把JS代碼寫在網頁中很普遍,也許那時候的JS并不太重要,只是用來做做驗證或一些花哨的效果而已。

  2,定義一個函數,賦值給html元素的onXXX屬性

 
<script type="text/javascript">
function clk(){}
</script>
<div onclick="clk()">Div2 Element</div>

  先定義函數clk,然后賦值給onclick屬性,這種方式也應該屬于上世紀90年代的流行寫法。比第一種方式好的是它把業務邏輯代碼都封裝在一個函數里了,使HTML代碼與JS代碼稍微有點兒分離,不至于第一種那么緊密耦合。

  3,使用element.onXXX方式

 
<div id="d3">Div3 Element</div>
<script type="text/javascript">
var d3 = document.getElementById('d3');
d3.onclick
= function(){ }
</script>

  這種方式也是早期的寫法,但好處是可以將JS與HTML完全分離,前提是需要給HTML元素提供一個額外的id屬性(或其它能獲取該元素對象的方式)。

  4,使用addEventListener或attachEvent

 
<div id="d4">Div4 Element</div>
<script type="text/javascript">
var d4 = document.getElementById('d4');
function clk(){alert(4)}
if(d4.addEventListener){
d4.addEventListener(
'click',clk,false);
}

if(d4.attachEvent){
d4.attachEvent(
'onclick',clk);
}

</script>

  這是目前推薦的方式,較前兩種方式功能更為強大,可以為元素添加多個事件handler,支持事件冒泡或捕獲,前三種方式默認都是冒泡。IE6/7/8仍然沒有遵循標準而使用了自己專有的attachEvent,且不支持事件捕獲。

  好,把方式4簡單的封裝下,  兼容標準瀏覽器及IE瀏覽器。注意attachEvent的第一個參數需要加上個"on",addEventListener第三個參數為false表示事件冒泡,attachEvent沒有第三個參數,默認就是冒泡,沒有捕獲。

 
/**
*
* @param {Object} el HTML Element
* @param {Object} type 事件類型
* @param {Object} fn 事件handler

*/
function addEvent(el, type, fn){
if(el.addEventListener){
el.addEventListener(type, fn,
false);
}
else{
el.attachEvent(
'on' + type, fn);
}
}

  好,用這個工具函數添加一個給document添加一個點擊事件。

 
function handler(){
alert(
this);
alert(arguments[
0]);
}
addEvent(document,
'click', handler);

  在Firefox等標準瀏覽器中,點擊頁面后將彈出 “[object HTMLDocument]”,及handler中的this就是document自身。但在IE6/7/8中this卻是window對象。這讓人不爽,修改下與標準瀏覽器統一。

 
function addEvent(el, type, fn){
if(el.addEventListener){
el.addEventListener(type, fn,
false);
}
else{
el[
'e' + fn] = function(){
fn.call(el, window.event);
}
el.attachEvent(
'on'+type, el['e'+fn]);
}
}
0
0
 
標簽:JavaScript
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()