• 技术文章 >web前端 >js教程

    javascript事件委托和jquery事件委托

    hzchzc2020-07-01 09:46:50转载70
    元旦过后,新年第一篇。
    初衷:很多的面试都会涉及到事件委托,前前后后也看过好多博文,写的都很不错,写的各有千秋,自己思前想后,为了以后自己的查看,也同时为现在找工作的前端小伙伴提供一个看似更全方位的解读事件委托的地方来认识了解他的原理,本篇文章汇总了两个版本的事件委托:javascript、jquery;

    事件委托的定义:

    利用事件冒泡,指定一个事件处理程序,就可以管理某一类型的所有事件。

    事件委托的优势:

    在下面的代码中p标签要实现的效果是鼠标点击p标签的时候背景色变为红色,以下是js、jq的处理方法

    <body>
        <p id="nodes">
          <P class="node_p">第一个p</P>
          <P class="node_p">第二个p</P>
          <P class="node_p">第三个p</P>
          <p id="childp">
              <p>这是子集菜单</p>
              <p>我是子集的p
                  <p>我是子集的p</p>
              </p>
          </p>
        </p>
        <button>点击加一</button>
      </body>

    一、js事件委托

    在js中不用事件委托的情况:获取页面中所有的p标签然后用for循环遍历给每一个元素增加事件处理函数

    let nodes = document.getElementById("nodes");
        let ps = document.getElementsByTagName("p");
        console.log(ps);
        let btn = document.getElementsByTagName("button")[0];
        let inner = 33;
    
        btn.onclick = function() {
          inner++;
          let p = document.createElement("p");
          p.innerHTML = inner + "新增的p标签啊";
          nodes.appendChild(p);
          console.log(ps);
        };
        for (let i= 0;i<ps.length;i++){
            ps[i].onclick= function(){
                this.style.background = 'red'
            }  
        }

    这时候在浏览器中运行之后进行测试,发现如图一所示的结果;

    a33b63920012d9be93917fb41ae992c.png

    那么js不用事件委托怎么给新增加的标签添加事件处理函数呢?解决方案如下:

    let nodes = document.getElementById("nodes");
        let ps = document.getElementsByTagName("p");
        console.log(ps);
        let btn = document.getElementsByTagName("button")[0];
        let inner = 33;
    
        btn.onclick = function () {
            inner++;
            let p = document.createElement("p");
            p.innerHTML = inner + "新增的p标签啊";
            nodes.appendChild(p);
            addEvent();//将新dom元素增加到页面后再执行循环函数
            console.log(ps);
        };
    
        function addEvent() {
            for (let i = 0; i < ps.length; i++) {
                ps[i].onclick = function () {
                    this.style.background = 'red'
                }
            }
        }
        addEvent() //先执行一遍循环

    这时候浏览器中运行如图二所示:

    996b3d1e53a03c618398ba287ca5d2c.png

    这时候虽然解决了为新增dom元素增加事件处理函数的问题,但是仔细考虑他的性能却是比之前都有所下降,究其原因就是又增加了一个事件处理函数(对象),又一次占用了内存;所以,这个时候就会用到事件委托,这时候事件委托的优势也有所体现出来:

    let nodes = document.getElementById("nodes");
        let ps = document.getElementsByTagName("p");
        console.log(ps);
        let btn = document.getElementsByTagName("button")[0];
        let inner = 33;
    
        btn.onclick = function () {
            inner++;
            let p = document.createElement("p");
            p.innerHTML = inner + "新增的p标签啊";
            nodes.appendChild(p);
            console.log(ps);
        };
    //事件委托,为nodes指定一个事件处理函数,处理nodes下为p标签的所有元素的cilck事件
        nodes.onclick= function(e){
            let ev = e || window.event
            let target = ev.target || ev.srcElement //srcElement IE浏览器
            //这里要判被处理元素节点的名字,也可以增加相应的判断条件 target.nodeName.toLowerCase() == 'p'||target.nodeName.toLowerCase() == 'span',但是要注意不要使用父级元素的名称,因为再点击子元素之间的空气的时候,由于事件冒泡他会给父级元素也增加相应的事件处理函数;因为返回的节点名称一般都是大写,所以这时要用toLowerCase()处理一下;
            if(target.nodeName.toLowerCase() == 'p'){ 
                target.style.background = 'green'
            }
        }

    这时候浏览器中运行的结果如图三所示:

    c3982b0cd15b942a9a88ea4995faaba.png

    二、jquery事件委托:

    相较于js事件委托,jquery事件委托的优势:执行事件委托的时候只有子元素会触发事件函数,而代为执行的父元素不会触发事件函数,因此不用去判断元素节点的名称;(注意这里的事件委托用的方法on,如果用bind方法父元素会触发事件函数)
    这里nodes节点下所有标签为p的子节点都被赋予事件处理函数;这里的子节点还可以是多个类似' p,span',需要注意这里面也不可以写同nodes一样的标签,否则点击元素之间的间隔会给nodes下的p赋予事件处理函数;如例二:
    例一:

    let inner = 33;
    //这里nodes节点下所有标签为p的子节点都被赋予事件处理函数;这里的子节点还可以是多个类似' p,span',需要注意这里面也不可以写同nodes一样的标签,否则点击元素之间的间隔会给nodes下的p赋予事件处理函数
    $('#nodes').on('click','p',function(e){
            let target = $(e.target)
            target.css('backgroundColor','red')
        })
        $('button').click(()=>{
            inner++;
            $('#nodes').append($('<p>我是新增加的p标签'+inner+'</p>'))
        })

    浏览器运行的效果如图四所示:

    b896ee2f5fcc6ce32db529e111eb206.png

    例二:

    <body>
        <p id="nodes">
            <P class="node_p">第一个p</P>
            <P class="node_p">第二个p</P>
            <P class="node_p">第三个p</P>
            <span class="node_p">span</span>
            <p id="childp">
                <p>这是子集菜单</p>
                <p>我是子集的p
                    <p>我是子集的p</p>
                </p>
            </p>
        </p>
        <button>点击加一</button>
    </body>
    <script>
    let inner =33;
    $('#nodes').on('click','p,p,span',function(e){
            let target = $(e.target)
            target.css('backgroundColor','red')
        })
        $('button').click(()=>{
            inner++;
            $('#nodes').append($('<p>我是新增加的p标签'+inner+'</p>'))
        })
    </script>

    浏览器运行效果如图五所示:

    f63369c0f69eaf8acbbc2aefe458577.png

    事件委托不仅仅只是为处理一种dom操作类型,他可以进行增删改查等功能:

    js事件委托:不同操作

    <body>
        <p id="events">
            <input type="button" id='addHandle' value='增加'>
            <input type="button" id='deleteHandle' value='减少'>
        </p>
        <p id="content">
    
        </p>
    </body>
    <script src='http://code.jquery.com/jquery-2.1.1.min.js'></script>
    <script>
        let events = document.getElementById('events');
        let content = document.getElementById('content');
        events.onclick=function(e){
            let ev = e || window.event;
            let target = ev.target || ev.srcElement;
            if(target.nodeName.toLowerCase()=='input'){
                switch(target.id){
                    case 'addHandle':
                    return addEvent();
                    break
                    case 'deleteHandle':
                    return deleteEvent();
                    break
                }
            }
        }
        function addEvent(){
            let add = document.createElement('p')
            add.innerHTML = '这是增加按钮'
            content.appendChild(add)
        }
        function deleteEvent(){
            let del = document.createElement('p')
            del.innerHTML = '这是删除按钮'
            content.appendChild(del)
        }
    </script>

    浏览器中的效果如图六所示:

    0a8d5b4d66b07fd22ac0cda71174190.png

    jquery事件委托:不同操作

    $('#events').on('click','input',(e)=>{
            let target = $(e.target);
            switch(target[0].id){
                    case 'addHandle':
                    return addEvent();
                    break
                    case 'deleteHandle':
                    return deleteEvent();
                    break
            }
        })
        function addEvent(){
            $('#content').append($('<p>这是增加按钮</p>'))
        }
        function deleteEvent(){
            $('#content').append($('<p>这是删除按钮</p>'))
        }

    浏览器中的效果如图七所示:

    17edd837d6993690b88d14500e0058c.png

    本文如有不实之处,还望大神指点一二,欢迎讨论!

    推荐教程:《JS教程

    以上就是javascript事件委托和jquery事件委托的详细内容,更多请关注php中文网其它相关文章!

    本文转载于:简书,如有侵犯,请联系a@php.cn删除
    专题推荐:javascript
    上一篇:JS对象基础知识的巩固学习笔记 下一篇:Vue中mounted和created的区别(图文详解)
    第12期线上培训班

    相关文章推荐

    • 为什么把JavaScript文件放在Html底部• 带你了解并掌握JavaScript函数的柯里化• javascript打包是什么意思• 一起来聊聊jQuery、JavaScript与JS三者间的区别

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网