zoukankan      html  css  js  c++  java
  • 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>
  • 相关阅读:
    左侧列固定的表格
    百度地图上添加多个标记,标记上添加信息展示窗口、跳转到导航界面
    vue-cli4版本解决eslint问题
    使用脚手架搭建项目
    正则表达式学习
    函数参数:
    装饰器(重点)
    列表生成式、生成器、迭代器
    logging 日志模块
    json 、 pickle 、shelve序列化
  • 原文地址:https://www.cnblogs.com/cherryshuang/p/8544780.html
Copyright © 2011-2022 走看看