js事件代理理解

Posted shuangcherry

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js事件代理理解相关的知识,希望对你有一定的参考价值。

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

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

事件代理就是利用了事件冒泡机制,将一个节点的事件处理,交给它的父级去处理。举个栗子:若为多个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>
        //简单的事件绑定函数
        var link1=document.getElementById(link1);
        // function on(ele,type,fn){
        //     ele.addEventListener(type,fn);
        // }
        // on(link1,‘click‘,function(e){
        //     e.preventDefault();
        //     alert(‘clicked‘);
        // })
        
        //事件代理
        var div1=document.getElementById(div1);
        // div1.addEventListener(‘click‘,function(e){
        //     e.preventDefault();
        //     if(e.target.nodeName===‘A‘){
        //         alert(‘clicked‘);
        //     }
        // })

        //完整的绑定事件函数
        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>

 

以上是关于js事件代理理解的主要内容,如果未能解决你的问题,请参考以下文章

JS代理模式实现图片预加载

js事件代理

性能优化之-事件代理

js中的事件委托/代理

简述:js事件代理的7种方法

JavaScript Promise理解