js中的事件委托

知识点温故而知新
什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件。

也就是:利用冒泡的原理,把事件加到父级上,触发执行效果。

好处呢:1,提高性能。

我们可以看一个例子:需要触发每个li来改变他们的背景颜色。

<ul id="ul">
    <li>aaaaaaaa</li>
    <li>bbbbbbbb</li>
    <li>cccccccc</li>
</ul>
window.onload = function(){
    var oUl = document.getElementById("ul");
    var aLi = oUl.getElementsByTagName("li");

    for(var i=0; i<aLi.length; i++){
        aLi[i].onmouseover = function(){
            this.style.background = "red";
        }
        aLi[i].onmouseout = function(){
            this.style.background = "";
        }
    }
}

这样我们就可以做到li上面添加鼠标事件。

但是如果说我们可能有很多个li用for循环的话就比较影响性能。

下面我们可以用事件委托的方式来实现这样的效果。html不变

window.onload = function(){
    var oUl = document.getElementById("ul");
    var aLi = oUl.getElementsByTagName("li");

/*
这里要用到事件源:event 对象,事件源,不管在哪个事件中,只要你操作的那个元素就是事件源。
ie:window.event.srcElement
标准下:event.target
nodeName:找到元素的标签名
*/
    oUl.onmouseover = function(e){
        var e = e || window.event;
        var target = e.target || e.srcElement;
        if(target.nodeName.toLowerCase() == "li"){
        target.style.background = "red";
        }
    }
    oUl.onmouseout = function(e){
        var e = e || window.event;
        var target = e.target || e.srcElement;
        if(target.nodeName.toLowerCase() == "li"){
        target.style.background = "";
        }
    }
}

好处2,新添加的元素还会有之前的事件。

我们还拿这个例子看,但是我们要做动态的添加li。点击button动态添加li

如:

<input type="button" id="btn" />
<ul id="ul">
    <li>aaaaaaaa</li>
    <li>bbbbbbbb</li>
    <li>cccccccc</li>
</ul>

不用事件委托我们会这样做:

window.onload = function(){
    var oUl = document.getElementById("ul");
    var aLi = oUl.getElementsByTagName("li");
    var oBtn = document.getElementById("btn");
    var iNow = 4;
    for(var i=0; i<aLi.length; i++){
        aLi[i].onmouseover = function(){
            this.style.background = "red";
        }
        aLi[i].onmouseout = function(){
            this.style.background = "";
        }
    }

    oBtn.onclick = function(){
        iNow ++;
        var oLi = document.createElement("li");
        oLi.innerHTML = 1111 *iNow;
        oUl.appendChild(oLi);
    }


}

这样做我们可以看到点击按钮新加的li上面没有鼠标移入事件来改变他们的背景颜色。因为点击添加的时候for循环已经执行完毕。

那么我们用事件委托的方式来做。就是html不变

window.onload = function(){
    var oUl = document.getElementById("ul");
    var aLi = oUl.getElementsByTagName("li");
    var oBtn = document.getElementById("btn");
    var iNow = 4;

    oUl.onmouseover = function(e){
        var e = e || window.event;
        var target = e.target || e.srcElement;
        if(target.nodeName.toLowerCase() == "li"){
        target.style.background = "red";
        }
    }
    oUl.onmouseout = function(e){
        var e = e || window.event;
        var target = e.target || e.srcElement;
        if(target.nodeName.toLowerCase() == "li"){
        target.style.background = "";
        }
    }
    oBtn.onclick = function(){
        iNow ++;
        var oLi = document.createElement("li");
        oLi.innerHTML = 1111 *iNow;
        oUl.appendChild(oLi);
    }
}

后记

通过上面的例子可以清楚的看到什么是js的事件委托,当然也可以用第三方类库的一些方法实现,比如jq的on、delegate、live等。
<think> 首先,用户的问题是:“我想了解JavaScript事件委托原理 请问JavaScript事件委托原理”。这是一个关于JavaScript事件委托原理的查询。 从系统级指令看: - 所有行内数学表达式必须使用$...$格式,但这个主题是JavaScript事件委托,不涉及数学表达式,所以这条可能不适用。 - 独立公式必须使用$$...$$格式并单独成段,同样,这里没有公式。 - LaTeX语法正确:由于没有数学内容,不需要。 - 使用中文回答:是的,必须用中文。 - 生成相关问题:指令中说“生成相关问题”,并且有示例显示在回答末尾添加相关问题。 - 回答中引用的段落末尾自然地添加引用标识:引用来自提供的引用[1]到[4],所以我需要在回答中引用这些来源时添加标识,如[^1]、[^2]等。 用户提供的引用: - [^1]: 事件委托也叫事件代理,利用事件冒泡,只指定一个事件处理程序管理某一类型的所有事件。 - [^2]: 事件委托是利用事件冒泡机制,将子元素事件统一委托给父元素,减少事件监听器数量,提升性能,支持动态元素绑定。 - [^3]: 事件委托原理基于事件冒泡,事件从最深节点向上传播;示例说明给父元素加事件处理程序可以处理子元素事件。 - [^4]: 事件委托解决为大量动态DOM元素绑定事件的问题,减少性能负担和代码复杂性。 用户的问题是“JavaScript事件委托原理”,所以我需要基于这些引用解释原理。 结构化回答: - 回答应该结构清晰,帮助用户逐步解决问题。 - 尽可能保证真实可靠,基于提供的引用。 关键原理: - 事件委托的核心是事件冒泡机制。 - 事件从目标元素向上冒泡到父元素。 - 通过将事件处理程序绑定到父元素,而不是每个子元素,来处理多个子元素的事件。 - 这样可以减少事件监听器的数量,提高性能,尤其是对于动态添加的元素。 步骤构建回答: 1. 引入概念:什么是事件委托(基于引用[1]和[^4])。 2. 解释原理事件冒泡机制(基于引用[^3])。 3. 描述优点:减少监听器、提升性能、支持动态元素(基于引用[^2]和[^4])。 4. 给出简单示例:可能参考引用[^3]中的代码示例。 5. 添加引用标识:在相关部分末尾自然添加[^1]、[^2]等。 6. 生成相关问题:在末尾添加相关问题。 相关问题生成: - 类似示例中的快速排序问题列表。 - 基于主题,如:事件委托应用场景、如何实现事件委托事件委托事件冒泡的关系等。 完整回答结构: - 开头简要介绍事件委托。 - 详细解释原理。 - 讨论优点和为什么使用它。 - 结束语。 - 相关问题部分。 确保语言清晰、中文。 </think> ### JavaScript事件委托原理 事件委托(也称为事件代理)是JavaScript中一种高效的事件处理技术,其核心原理基于DOM事件中的**事件冒泡机制**。下面我将逐步解释事件委托原理、工作原理和优势,确保内容清晰易懂。 #### 1. **事件冒泡机制的核心原理** - 在DOM(文档对象模型)中,当一个事件(如点击事件)在子元素上触发时,它会沿着DOM树从目标元素向上“冒泡”到父元素,直至文档根节点[^3]。例如,对一个嵌套结构 `div > ul > li > a`: - 当点击 `a` 元素时,事件会依次冒泡到 `li`、`ul`、`div`。 - 事件委托就是利用这个特性:将事件处理程序绑定到父元素(如 `ul` 或 `div`),而不是绑定到每个子元素(如 `li` 或 `a`)。当子元素事件发生时,它会自动冒泡到父元素,父元素的事件处理程序可以捕获并处理该事件[^1][^3]。 #### 2. **事件委托的工作原理** - **统一处理代替逐个绑定**:传统方法是为每个子元素单独绑定事件监听器(例如,为每个 `li` 元素添加点击处理函数)。这会导致大量监听器,增加内存消耗和性能开销。事件委托则只在父元素上设置一个监听器,通过事件对象的 `event.target` 属性来判断事件源,从而决定如何处理[^2][^4]。 - 示例代码(基于引用[^3]的简化版本): ```html <body> <ul id="myList"> <li>111</li> <li>222</li> <li>333</li> </ul> <script> document.getElementById('myList').addEventListener('click', function(event) { if (event.target.tagName === 'LI') { // 检查事件源是否为li元素 console.log('Clicked item: ' + event.target.textContent); // 输出被点击的li内容 } }); </script> </body> ``` - 在这个示例中,父元素 `ul` 委托处理所有子元素 `li` 的点击事件。当用户点击任何 `li` 时,事件冒泡到 `ul`,事件处理程序通过 `event.target` 识别具体被点击的 `li`,避免了为每个 `li` 单独绑定的麻烦[^3][^4]。 #### 3. **事件委托的优势** - **减少事件监听器数量**:只需一个父元素监听器,就能管理所有子元素的事件,显著减少内存占用和性能开销(尤其在数百或数千个元素的场景下)[^2][^4]。 - **支持动态元素**:对后续动态添加的元素(如通过JavaScript添加的新 `li`),事件委托自动生效,无需重新绑定,因为事件冒泡机制始终有效[^1][^2]。 - **增强代码可维护性**:逻辑集中在父元素的一个处理程序中,便于调试和扩展,避免代码分散[^2][^4]。事件委托也简化了事件处理,避免了事件处理程序的重复设置。 #### 总结 事件委托原理本质上是通过事件冒泡,将子元素的事件处理“委托”给父元素统一管理。这不仅优化了性能,还提升了代码的灵活性和可维护性。在实际开发中,事件委托常用于列表、菜单、表格等需要处理多个相似元素的场景[^1][^2][^4]。 如需深入了解事件委托应用或优化技巧,可以参考相关文档或资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值