• 事件代理


      由于事件会在冒泡阶段向上传播到父节点,因些可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件代理(delegation),也可以叫做事件委托。简单来说,它是基于事件冒泡,只制定一个时间来处理程序,就可以管理某一类型的所有行为绑定事件。可以看出它们要用到事件目标的target和srcElement属性。

      举一个简单的例子来说,页面上有如下代码,想要给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a->li->ul。现在我们给最外面的ul加上点击事件,那么里面的li,a执行点击事件的时候,都会冒泡到最外层的div上都会触发,这就是事件委托。

        <ul>
            <li>
                <a href="javascript:;"></a>
            </li>
        </ul>

      如下面的代码中,我们想实现点击一下按钮可以新增2个li,且每个li在点击的时候都能弹出我是第几个li这一需求给动态的元素绑定事件。

        <link rel="stylesheet" href="./css/reset.min.css" />
        <style>
          .box {margin: 20px auto; 200px;}
          .newList {box-sizing: border-box;border: 2px solid #bbbbbb;padding: 5px;}
          .newList li { line-height: 35px;border-bottom: 1px dotted #cccccc;}
          .createBtn {box-sizing: border-box;margin-top: 10px; 80px;height: 30px; border: 1px solid #cccccc;}
          
        </style>
        <div class="box">
          <ul class="newList">
            <li>我是第1个li</li>
            <li>我是第2个li</li>
          </ul>
          <button class="createBtn">新增按钮</button>
        </div>

      我们用到jQuery可以更加方便的操作DOM,在没有用事件委托之前,我们用循环绑定。可以先写一个headle方法,在这个方法中,我们先获取所有的li,然后遍历每一个lis让其弹出“我是第几个li”。然后给按钮绑定事件,点击增加2个li。刚开始我们执行一次headle方法,然后给按键绑定事件增加li后再执行一次headle方法。这样一看我们操作DOM的次数过于频繁,引起浏览器重绘与重排的次数。这样很消耗性能。

        <script src="../../node_modules/jquery/dist/jquery.min.js"></script>
        <script>
          let $newList = $(".newList"),
            $lis = null,
            $createBtn = $(".createBtn");
          function handle() {
            $lis = $newList.children("li");
            $lis.each(function (index, item) {
              $(item).click(function () {
                alert(`我是第${index + 1}个li`);
              });
            });
          }
          handle();
          let count = 2;
          $createBtn.click(function () {
            let str = ``;
            for (let i = 0; i < 2; i++) {
              count++;
              str += `<li>我是第${count}个li</li>`;
            }
            $newList.append(str);
            handle();
          });

        这里用父级newList做事件处理。当li点击时,由于冒泡机制,事件会冒泡到newList上,newList上的事件就会被触发。当然我们点击newList时这个事件也会触发,这时就需要用到Event对象提供的target属性,它可以返回事件的目标节点,我们称之为事件源,这时我们只是获取了当前节点的位置并不知道节点的名称,这时要用到tagName来获取具体是什么标签名(这里标签名是大写)具体代码如下,这样的话每次只执行一次DOM操作,大大减少了DOM的操作,进行了性能上的优化。但使用“事件委托”时,并不是把事件委托给的元素越靠近顶层就越好。如果DOM嵌套结构很深,事件冒泡通过大量祖先元素也会导致性能损失。

    let $newList = $(".newList"),
            $createBtn = $(".createBtn"),
            count =2;
    
          $newList.click(function (ev) {
            let target = ev.target,
              $target = $(target);
            target.tagName === "LI"
              ? alert(`我是第${$target.index()+1}个li`)
              : null;
          });
    
          $createBtn.click(function () {
            let str = ``;
            for (let i = 0; i < 2; i++) {
              count++;
              str += `<li>我是第${count}个li</li>`;
            }
            $newList.append(str);
          }); 

      

  • 相关阅读:
    错误:严重: Servlet.service() for servlet [appServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is
    转 File "/usr/bin/yum", line 30 except KeyboardInterrupt, e:
    【转】C++和Java比较
    org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'xxxx' is not present
    Leetcode 423. Reconstruct Original Digits from English
    Maven中打包scope为system的Jar包
    Oracle常用函数和注意事项
    Vue中组件之间数据通信
    Vue中data数据响应问题
    JAVA爬虫对font-face字体反爬虫解密
  • 原文地址:https://www.cnblogs.com/davina123/p/13030407.html
Copyright © 2020-2023  润新知