javascript事件委托的方式绑定详解

js事件绑定

事件绑定,这里使用了冒泡的原理,从点击的元素开始,递归方式的向父元素传播事件,这样做的好处是对于大量要处理的元素,不必为每个元素都绑定事件,只需要在他们的父元素上绑定一次即可,提高性能。还有一个好处就是可以处理动态插入dom中的元素,直接绑定的方式是不行的。

之前一直使用的是jquery的on方法做这样的事情,前几天看到公司项目中有实现这种方式的源代码,拿来仔细研究研究,跟大家分享分享。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 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,其他的都不会触发事件

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <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>

效果如下:

再看看事件的绑定情况,跟我们绑定事件的情况一致:

以上所述就是本文的全部内容了,希望大家能够喜欢。

返回顶部
跳到底部

Copyright 2011-2024 南京追名网络科技有限公司 苏ICP备2023031119号-6 乌徒帮 All Rights Reserved Powered by Z-BlogPHP Theme By open开发

请先 登录 再评论,若不是会员请先 注册