攀大

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

  javascript事件是所有网页互动性的根本,因此在我们编写前端交互的时候,事件绑定作为再普通不过的交互操作了。在传统的事件处理中,你根据需求给每一个元素添加或者 删除事件处理器,然而事件处理器可以导致内存泄露或者性能下降(你用的越多风险越大)。例如以下例子

一:当我们点击每个li时,控制台打出 当前点击元素的 innerHtml 

1 <ul id="ul">
2   <li>aaaaaaaa</li>
3   <li>bbbbbbbb</li>
4   <li>cccccccc</li>
5 </ul>

 传统的做法:为每个li绑定点击事件:

1 window.onload = function(){
2     var ul = document.getElementById("ul");
3     var lis = ul.getElementsByTagName("li");
4     for(var i = 0 ; i < lis.length; i ++){
5         lis[i].onclick = function(){
6             console.log(this.innerHTML);
7         }
8     }
9 }

这样我们就可以做到li上面添加鼠标事件,但是如果说我们可能有很多个li用for循环的话就比较影响性能。

实际开发情况中,我们的li大多数是根据数据集合,动态组装生成的。此时就需要我们每生成一个li 就给这个li 绑定一个点击事件。效率低,容易出错

思考:1.有没有一种可行的方法让我每次只需完成一次事件绑定的操作?

   2.或者我在li的父容器上,加入某种事件,让我在每次点击li时,由父容器的事件判断我当前点击的哪个li元素,并执行特定的操作?

答:事件代理。

下面我们可以用事件代理的方式来实现这样的效果。html不变

 1 window.onload = function(){
 2     var ul = document.getElementById("ul");
 3     var lis = ul.getElementsByTagName("li");
 4     
 5     ul.onclick = function(e){
 6         /*
 7         这里要用到事件源:event 对象,事件源,不管在哪个事件中,只要你操作的那个元素就是事件源。
 8         ie:window.event.srcElement
 9         标准下:event.target
10         nodeName:找到元素的标签名
11         */
12         var e  = e || window.event;
13         var target = e.target || e.srcElement;
14         if(target.nodeName.toUpperCase() == "LI"){
15             alert(target.innerHTML);
16         }
17     }
18 }

这样,我们就使用事件代理完成在父容器绑定点击事件,当我们点击子元素li时,根据事件源得到当前点击的target元素。这样就算li是动态生成的,在点击的时候也会去获取到新的节点li。并执行对应操作。

原理:事件冒泡以及目标元素。当一个元素的事件被触发时,同样的事件将会在这个元素的所有祖先元素中被触发,这一过程称之为事件冒泡。这个事件从原始元素一直冒泡到dom树最上层。并且所有的事件触发的目标元素都是最开始的元素(target || srcElement)因此我们可以根据这一原理来达到触发原始元素事件的目的。

这样做的好处:

  1.将所有同类元素的事件操作代理给其父元素,减少了事件绑定过程,避免了100个li,1000个li 或者更多li的循环绑定事件,有效减少内存占用,避免元素过多导致浏览器内存泄露,提高效率。

  2.在DOM更新后无须重新绑定事件处理器了。

注:1.并不是所有的时间都允许事件冒泡,blur、focus、load和unload不能像其它事件一样冒泡

  2.阻止事件冒泡操作:event.stopPropagation();

 

总结:了解事件代理的原理后,实现起来就很简单了。事件代理大大减少了事件处理器的增加删除操作。开发过程中,根据实际的项目需求,合理使用事件代理 以来提高浏览器效率。 一些主流类库也提供了事件代理示例,例如(jquery)等。

 

 

    

 

 

 

 

  

 

posted on 2016-06-24 16:02  攀大  阅读(220)  评论(0编辑  收藏  举报