DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> javascript事件委托的方式綁定詳解
javascript事件委托的方式綁定詳解
編輯:關於JavaScript     

js事件綁定

事件綁定,這裡使用了冒泡的原理,從點擊的元素開始,遞歸方式的向父元素傳播事件,這樣做的好處是對於大量要處理的元素,不必為每個元素都綁定事件,只需要在他們的父元素上綁定一次即可,提高性能。還有一個好處就是可以處理動態插入dom中的元素,直接綁定的方式是不行的。

之前一直使用的是jquery的on方法做這樣的事情,前幾天看到公司項目中有實現這種方式的源代碼,拿來仔細研究研究,跟大家分享分享。

function $bindAction(dom, event, listeners) {
 #這裡的dom為綁定事件的元素,比如document.body
 #event為綁定的事件,比如click
 #listeners是待執行的事件對象
 $addEvent(dom, event, function(e) {
 #這裡獲取事件e
 #獲取點擊的元素src
 var e = e || window.event,
  src = e.target || e.srcElement,
  action,
  returnVal;

 #模擬冒泡的方式,先是src,然後是src.parentNode,再然後是src.parentNode.parent.Node
 #當前dom元素等於事件綁定的dom元素的時候,停止“冒泡”
 while (src && src !== dom) {
  #循環獲取dom元素的attr-action屬性,
  action = src.getAttribute('attr-action');
  #如果當前dom元素存在attr-action屬性,並且事件對象中有該屬性值的函數,執行這個函數
  #將事件e、當前dom元素、元素的屬性attr-action值傳給要執行的函數
  if (listeners[action]) {
  returnVal = listeners[action]({
   src : src,
   e : e,
   action : action
  });
  #如果上面的函數執行之後返回false,停止繼續“冒泡”
  if (returnVal === false) {
   break;
  }
  }
  #獲取當前dom元素的父元素節點
  src = src.parentNode;
 }
 });
};

function $addEvent(obj, type, handle) {
 if(!obj || !type || !handle) {
 return;
 }
 #綁定事件到多個對象,遞歸調用
 if( obj instanceof Array) {
 for(var i = 0, l = obj.length; i < l; i++) {
  $addEvent(obj[i], type, handle);
 }
 return;
 }
 #綁定多個事件,遞歸調用
 if( type instanceof Array) {
 for(var i = 0, l = type.length; i < l; i++) {
  $addEvent(obj, type[i], handle);
 }
 return;
 }
 #下面這一大段用來記錄當前頁面一共綁定了多少個事件,以及事件的相關信息
 #以及某個對象上面綁定的事件id
 window.__allHandlers = window.__allHandlers || {};
 window.__Hcounter = window.__Hcounter || 0;
 function setHandler(obj, type, handler, wrapper) {
 obj.__hids = obj.__hids || [];
 var hid = 'h' + ++window.__Hcounter;
 obj.__hids.push(hid);
 window.__allHandlers[hid] = {
  type : type,
  handler : handler,
  wrapper : wrapper
 }
 }
 #這個裡面的apply是為了修改綁定事件所執行函數中的this
 #這個在低版本的IE中才真正起作用
 function createDelegate(handle, context) {
 return function() {
  return handle.apply(context, arguments);
 };
 }

 #綁定事件,記錄事件綁定信息
 if(window.addEventListener) {
 var wrapper = createDelegate(handle, obj);
 setHandler(obj, type, handle, wrapper)
 obj.addEventListener(type, wrapper, false);
 }
 else if(window.attachEvent) {
 var wrapper = createDelegate(handle, obj);
 setHandler(obj, type, handle, wrapper)
 obj.attachEvent("on" + type, wrapper);
 }
 else {
 obj["on" + type] = handle;
 }
};

看個例子:

當點擊前三個的時候會依次彈出classname,其他的都不會觸發事件

<style type="text/css">
#out{width: 500px;background-color: #CDE}
#inner{background-color: #ABCDEF;margin: 0;padding: 0;width: 400px;}
ul{background-color: pink;margin: 0;padding: 0;width: 400px;}
li{width:398px;height: 20px;border: 1px solid black;margin: 15px 0px;padding: 0px;list-style: none;}  
</style>
div#out > div#inner :
<div id="out">
 <ul id="inner">
 <li class="lia" attr-action="setWhat">class="lia" attr-action="setWhat"</li>
 <li class="lia" attr-action="setWhat">class="lia" attr-action="setWhat"</li>
 <li class="lib" attr-action="setWhat">class="lia" attr-action="setWhat"</li>
 <li class="lib">class="lib"</li>
 <li class="lib">class="lib"</li>
 <li class="lib">class="lib"</li>
 </ul>
</div>
ul :
<ul>
 <li class="lia" attr-action="setWhat">class="lia" attr-action="setWhat"</li>
 <li class="lia" attr-action="setWhat">class="lia" attr-action="setWhat"</li>
 <li class="lib" attr-action="setWhat">class="lia" attr-action="setWhat"</li>
 <li class="lib">class="lib"</li>
 <li class="lib">class="lib"</li>
 <li class="lib">class="lib"</li>
</ul>

<script>
listeners = {
 setWhat : function(opts) {
 alert(opts.src.className);
 return false;
 },
};
window.onload = function(){$bindAction(document.getElementById('out'), ['click', 'mouseover'], listeners);}
</script>

效果如下:

再看看事件的綁定情況,跟我們綁定事件的情況一致:

以上所述就是本文的全部內容了,希望大家能夠喜歡。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved