说一说方便高效的事件代理

本文通过实例讲解事件代理(事件委托)的概念及其在Web开发中的应用,包括如何使用事件代理解决大量DOM元素事件绑定的问题,并提供了一个封装事件代理方法的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天我来实际测试说明一下我所理解的事件代理(事件委托),如有问题欢迎各位指正。

先说说事件代理的概念吧,上面我在事件代理后面加了个括弧,里面又写了个“事件委托”,这里我想先申明一下,这俩名字,说的就是一个意思,之前我一度认为,这是两个东西,其实不是。什么是事件代理?“代理”,顾名思义,就是交给其他人(或物)代办,事件代理就是把事件注册到目标元素的祖先元素上面,再通过实际执行中,判断事件源来确定具体的执行对象。那么,它的作用或者说是带来的好处在哪儿呢?具体又是怎样实现的呢?下面,我们来看看具体的操作。

前段时间我在做公司官网,其中有一个房源列表的部分,需要给列表中的每个元素添加特效,而房源列表的数量是不确定的,即时确定,假如有一百个列表元素,难道我要给其注册100次事件嚒?如果是1000个、2000个房源乃至更多呢?再有,如果是动态添加上去的列表元素,它是得不到事件的,这里就会用到事件代理,我将其简化,用两种方式表现,示例如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css" rel="stylesheet">
        body,ul{
            margin: 0px;
            padding: 0px;
        }
        ul{
            list-style: none;
            width: 100%;
            margin: 0 auto;
        }
        li{
            width: 200px;
            height: 200px;
            border: 1px solid #8c8c8c;
            text-align: center;
            cursor: pointer;
            margin-left: 50px;
            display: inline-block;
        }
    </style>
</head>
<body>

<ul id="newHouse">
    <li class="houseNum">泰和公馆</li>
    <li class="houseNum">绿地世纪城</li>
    <li class="houseNum">罗浮宫</li>
    <li class="houseNum">尚景雅筑</li>
</ul>

</body>
<script type="text/javascript">
    /*现在我要获取鼠标移上的li的文本,通常这样做*/
    var newHouse = document.getElementById('newHouse');
    var liArr = document.getElementsByTagName('li');
    for(var i=0; i<liArr.length; i++){
        liArr[i].onmouseover = function(){
            alert(this.innerText);
        };
    }
</script>
</html>

这样做,有两个问题,其一:如果现在用js动态追加一个li,那么这个li是没有获取文本的事件的,因为事件是循环注册到前面四个li上面的;其二:如果li有成千上万个,一个循环固然可以简单地把事件加上去,但是那就相当于注册了成千上万的EventHandler,那就需要开辟内存来存放这些Hander,这对浏览器来说是个负担,影响性能,现在,我换个方式,html不变,只把js换一下,但是效果依旧,看代码:

<script type="text/javascript">
    /*现在我改用事件代理来获取鼠标移上的li的文本*/
    var newHouse = document.getElementById('newHouse');
    newHouse.onmouseover = function(e){
        var e = e || window.event;
        var myTarget = e.target || e.srcElement;
        //alert(target.innerHTML);
        if(myTarget.nodeName.toLowerCase() == "li"){
            alert(myTarget.innerText);
        }
    }
</script>

上述代码亲测有效,解决了第一种方式存在的两个问题,现在再来说说它的原理。对比两个方法的js,我们发现,第一种是将事件绑定到元素自身,而第二种是将事件注册到父级元素上面,通过冒泡机制,从父级来判断哪个元素触发了事件,这里的判断十分巧妙地用到了target这个东西,然后通过target来进行后续的操作,这就是事件代理!

下面,我尝试封装一个事件代理的方法:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css" rel="stylesheet">
        body{
            margin: 0px;
            padding: 0px;
        }
        #newEvent{
            width: 200px;
            margin: 0 auto;
            background-color: #6495ed;
        }
        p,h3{
            text-align: center;
            cursor: pointer;
            margin: 0px;
            border: 1px solid red;
        }
        #newEvent>div{
            width: 100%;
            height: 20px;
            text-align: center;
            cursor: pointer;
        }
    </style>
</head>
<body>

<div id="newEvent">
    <p>hello</p>
    <h3>嗨</h3>
    <div>小贱</div>
</div>

</body>
<script type="text/javascript">
    var newHouse = document.getElementById('newEvent');

    EventTarget.prototype.showTxt = function(yourEle, eventType, yourEvent) {
        this.addEventListener(eventType, function(e) {
            if (e.target.tagName === yourEle.toUpperCase()) {
                yourEvent(e);
            }
        });
    };
    newHouse.showTxt('p','mouseover',function(e){
        alert(e.target.innerText + '我是p标签的文本')
    });
    newHouse.showTxt('h3','mouseover',function(e){
        alert(e.target.innerText + '我属于h3')
    });
    newHouse.showTxt('div','mouseover',function(e){
        alert(e.target.innerText + '我属于div的文本')
    });
</script>
</html>

只是一个简单的封装,不喜勿喷,end!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值