zoukankan      html  css  js  c++  java
  • 说说事件委托

    事件委托,说白了就是本来你要给一个元素添加一个事件(比如点击),出于某些考率,现在要把事件添加给它的外层元素。

    事件源

    解释事件委托之前,应该先了解下事件源。简单来说,事件源就是直接触发事件的元素。在事件函数中可通过event对象的target属性访问事件源。

    看一个例子:

    图中,单击span部分,控制台会打印出对应span元素;单击span外的p部分,会打印出对应p元素;单击p外的div部分,会打印出对应div元素。

    关键代码如下:

     1     <body>
     2         <div id="box">div
     3             <p>p
     4                 <span>span</span>
     5             </p>
     6         </div>
     7     </body>    
     8     <script>
     9         window.onload=function(){
    10             var box=document.getElementById("box");
    11             box.onclick=function(ev){
    12                 console.log((ev || window.event).target);
    13             };
    14     </script>

    事件委托

    再说事件委托。通常,我们用事件委托解决两问题:1、避免不必要的性能开销;2 、新生成的元素不需要重新添加事件。

    先看一个经典的例子:

    例子中,我们希望点击li能打印对应的文本。

     1     <body>    
     2         <ul id="list">
     3             <li>red</li>
     4             <li>green</li>
     5             <li>blue</li>
     6             <li>pink</li>
     7             <li>black</li>
     8         </ul>
     9     </body>
    10     <script>
    11         var list=document.getElementById("list");
    12         var lis=document.querySelectorAll("li");
    13         
    14         for(var i=0;i<lis.length;i++){
    15             lis[i].onclick=function(){
    16                 console.log(this.firstChild.nodeValue);   //本来单击li,可以打印出其对应文本
    17             };
    18         }
    19         
    20         list.innerHTML+='<li>yellow</li>';   //这里加了一行后,单击li就无法打印出li对应文本了    
    21     </script>    

    本来,单击li是可以在控制台打印对应文体的。但是,现在20行加了一行代码,单击li就无法打印出li对应文本了。因为innerHTML会将原有内容全部清空,再赋予新内容,所以li绑定的单击事件也将失效。类似这种情况的还有,使用cloneNode(),新节点不会复制源节点的事件;jQuery中通过remove()移除的节点,重新添加回来后,之前绑定的事件将失效。(PS:detach()在这点上与remove()不同。)

    下面,我将上面代码中的for循环换成以下代码:

    1              list.onclick = function(ev){
    2                  var ev = ev || window.event;
    3                  if(ev.target.tagName.toLowerCase()=='li'){
    4                      console.log(ev.target.innerHTML);    //单击li,即事件源是li是打印出其对应文本
    5                  }
    6              };

    这样就解决了刚才遇到的问题,而且避免了使用for循环。其实,在这个解决方案中,我们是把点击事件绑定在了li的父级元素ul身上,也就是所谓的事件委托。然后对事件源进行判断,等于间接地给li添加了点击事件。

       

    知识共享许可协议
    本作品采用知识共享署名 4.0 国际许可协议进行许可。

  • 相关阅读:
    css单位及颜色值
    web表单作业
    打卡第一天
    IIS的应用池-网站
    Sublime 提示 The package specified, DocBlockr, is not available
    Git/GitHub 初用体验与总结
    自定义置顶TOP按钮
    Firebug 学习使用教程
    ASP.NET导出文件FileResult的使用
    DataGrid获取当前行某列值
  • 原文地址:https://www.cnblogs.com/fortunel/p/6553046.html
Copyright © 2011-2022 走看看