关于事件冒泡和事件代理,看这一篇就够了!(下篇)

接着上篇的节奏走,上篇文章我们介绍了事件冒泡的过程及解决方法。

这期带来事件代理~~

事件代理这个名词其实经常出现,在面试的时候,有一个高频问题,假如现在有需求,需要操作10000个DOM节点,你会怎么做?

就比如我们上篇用的案例,一个ul,内部有n个li。我现在要求你操作DOM,生成10000个li,并且分别给他们的点击事件绑定处理函数,输出自己的内容。

这种问题,显然不能用常规的办法,常规的办法,早就累死了。

其实面试官想考察的就是关于事件代理的相关内容。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .father {
      
      
            width: 200px;
            height: 200px;
            border: 1px solid #000;
        }
        .child {
      
      
            width: 100px;
            height: 100px;
        }
        .child.child-1 {
      
      
            background-color: red;
        }
        .child.child-2 {
      
      
            background-color: orange ;
        }
    </style>
</head>
<body>
    <div class="father">
        <div class="child child-1"></div>
        <div class="child child-2"></div>
    </div>
    <script>
        var oFather = document.getElementsByClassName('father')[0],
            oChild1 = document.getElementsByClassName('child-1')[0],
            oChild2 = document.getElementsByClassName('child-2')[0];
        oFather.onclick = function(e) {
      
      
            var e = e || window.event;
            console.log(e);

        }
    </script>
</body>
</html>

还是上期的代码,我们把child-1child-2的点击事件取消,只保留它们的父类father的点击事件处理函数。并且在点击事件内容输出e
我们看下结果:
在这里插入图片描述

在输出结果中,往下找,有一个target属性,可以看到,被点击的元素其实被保存到了这个target属性里,那么我们分别输出一下它的classNametagName看看能否打印出来。

在这里插入图片描述

可以看到是可以的,即使我们不给子元素绑定任何的事件,也是可以通过父元素拿到它的classNametagName的,这和直接操作它的DOM节点效果其实是差不多的。

这样,一个很棒的想法就冒了出来,既然我从父元素的点击事件中也可以拿到子元素的节点信息,那么我是不是就可以通过这个来区分子元素,并且绑定它对应的点击事件处理函数。

对的,这其实就是事件代理的思路,通过父元素来触发其子元素的某些事件,达到一个代理效果。

下面我贴一下完全代码。、

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .father {
      
      
            width: 200px;
            height: 200px;
            border: 1px solid #000;
        }
        .child {
      
      
            width: 100px;
            height: 100px;
        }
        .child.child-1 {
      
      
            background-color: red;
        }
        .child.child-2 {
      
      
            background-color: orange ;
        }
    </style>
</head>
<body>
    <div class="father">
        <div class="child child-1"></div>
        <div class="child child-2"></div>
    </div>
    <script>
        var oFather = document.getElementsByClassName('father')[0],
            oChild1 = document.getElementsByClassName('child-1')[0],
            oChild2 = document.getElementsByClassName('child-2')[0];
        oFather.onclick = function(e) {
      
      
            var e = e || window.event,
                tar = e.target || e.srcElement, //兼容IE
                tagName = tar.tagName.toLowerCase();
                className = tar.className;
            switch(className) {
      
      
                case 'child child-1':
                    console.log('child-1');
                    break;
                case 'child child-2':
                    console.log('child-2');
                    break;
                case 'father':
                    console.log('father');
                    break;
                default:
                    break;
            }

        }
    </script>
</body>
</html>

这里面其实还有几个问题。

什么时候用tagName,什么时候用className呢?

当然要看实际的情况,如果子标签都是相同的,全是div,那么肯定不能通过tagName来,因为它们的tagName都是DIV。还有就是如果使用tagName,记得转成小写,因为tagName默认都是大写的。

如何兼容IE?

作为一个有素养的程序员,一定要考虑兼容问题,其实代码里我已经写出来了,如果要兼容IE浏览器,就把e.target换成e.srcElement,它们是一样的。

在这里插入图片描述
通过三次点击,可以看到,它正确的输出了各自应该输出的内容,这就很棒了~~

ok,关于事件冒泡事件代理的相关内容就介绍到这里,有任何问题欢迎讨论交流。还有就是,我最近在找实习,有渠道的也可也i联系我哈~~

联系方式
QQ:505417246
微信:18331092918
微信公众号:Code程序人生

Guess you like

Origin blog.csdn.net/m0_46171043/article/details/117279036