js事件代理理解

说到事件代理,首先得知道js的事件冒泡机制。

事件冒泡是指在一个dom节点触发一个事件比如click事件以后,这个事件会继续往节点的父节点传递,若父节点也绑定了click事件,则同样会触发父节点的click事件,然后继续往父节点的父节点传递....由内层往外层传递。

事件代理就是利用了事件冒泡机制,将一个节点的事件处理,交给它的父级去处理。举个栗子:若为多个li标签绑定事件。

1.一般的事件绑定方法:

1 <ul id="list">
2         <li>1</li>
3         <li>2</li>
4         <li>3</li>
5         <li>4</li>
6         <li>5</li>
7     </ul>
1 <script>
2         var list=document.getElementById('list');
3         var lis=list.getElementsByTagName('li');
4         for(var i=0;i<5;i++){
5             lis[i].addEventListener('click',function(){
6                 alert('li click');
7             })
8         }
9 </script>

2.使用事件代理

1 <script>
2     var list=document.getElementById('list');
3     // 让li的父节点绑定click事件,然后在内部判断事件触发的目标是否是li标签,如果是的话,执行相应操作,这样能达到直接绑定li标签同样的效果,且只用绑定一次
4     list.addEventListener('click',function(e){  //
5         if(e.target.nodeName==='LI'){
6             alert('li click');
7         }
8     })
9 </script>

从以上可以看出在使用事件代理可以减少dom操作,优化性能。使用代理还有一个好处就是:

例如在给动态加载的img图片绑定事件时,使用代理就不用每次给新增的标签绑定事件。例如:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>事件代理</title>
 6 </head>
 7 <body>
 8     <div id="box">
 9         <img src="" alt="1">
10         <img src="" alt="2">
11         <img src="" alt="3">
12         <img src="" alt="4">
13         <img src="" alt="5">
14         <!-- 下面还有很多需要动态加载的图片 -->
15     </div>
16     <button id="addImg">添加图片</button>
17     <script>
18         var box=document.getElementById('box');
19         var i=5;
20         var btn=document.getElementById('addImg');
21         btn.addEventListener('click',function(){
22             var img=document.createElement('img');
23             i++;
24             img.alt=i;
25             box.appendChild(img);
26         })
27         // 使用事件代理
28         box.addEventListener('click',function(e){
29             if(e.target.nodeName==='IMG'){
30                 alert('img click');
31             }
32         });
33         //不使用事件代理时,新增的图片没有事件绑定,需要重新绑定才行
34         /*var imgs=box.getElementsByTagName('img');
35         for(var j=0;j<i;j++){
36             imgs[j].addEventListener('click',function(){
37                 alert('img click');
38             })
39         }*/
40     </script>
41 </body>
42 </html>

3.写一个通用的事件绑定函数,既可以使用代理,也可以不使用代理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件</title>
</head>
<body>
    <div id="div1">
        <a href="http://imooc.com" id="link1">imooc.com</a>
        <a href="http://imooc.com" id="link2">imooc.com</a>
        <a href="http://imooc.com" id="link3">imooc.com</a>
        <a href="http://imooc.com" id="link4">imooc.com</a>
        <a href="http://imooc.com" id="link5">imooc.com</a>
        <a href="http://imooc.com" id="link6">imooc.com</a>
        <p id="p1">this is p1</p>
        <p id="p2">this is p2</p>
    </div>
    <hr>
    <div id="div2">
        <p id="p3">this is p3</p>
        <p id="p4">this is p4</p>
    </div>
    <script>
        //完整的绑定事件函数
        function bindEvent(ele,type,selector,fn){
            if(fn==null){
                fn=selector;
                selector=null;
            }
            var target;
            ele.addEventListener(type,function(e){
                if(selector){
                    //事件代理
                    target=e.target;
                    //element.matches(selector),返回true或false
                    if(target.matches(selector)){ 
                        fn.call(target,e);
                    }
                }else{
                    //非事件代理
                    fn(e);
                }
            });
        }
        bindEvent(div1,'click','a',function(e){
            e.preventDefault();
            alert(this.innerHTML);
        });
        var p1=document.getElementById('p1');
        bindEvent(p1,'click',function(e){
            alert(p1.innerHTML);
        });
    </script>
</body>
</html>

 

posted @ 2018-03-11 17:05  shuangcherry  阅读(199)  评论(0编辑  收藏  举报