前言
公司产品部推出了一款新产品,经理指派小A负责推广工作。小A通过多方打听了解到推广流程,需要使用公司证件在几个平台注册账号,并经过多轮审批。小A经历了一番操作后感到身心俱疲,最终成功将产品发布到公众平台上。
与此同时,公司的竞争部门也计划推出一款新产品。由于内部竞争关系,他们无法让小A协助推广。只能自己再注册一次。
时间过后,另一个部门X也面临类似的情况,老板觉得很繁琐,决定从公司层面成立宣传部,负责所有部门的宣传工作。
之后,任何部门有宣传的需求,都可以向上委托给宣传部,统一处理,提升了工作效率,减少了内部消耗
在现代Web开发中,当我们需要处理大量DOM元素的事件时,单个的事件绑定方式可能会导致代码冗长而难以维护,同时也会影响性能。幸运的是,JavaScript事件委托是一个优雅的解决方案,它可以优化代码结构并提升性能。让我们来深入了解什么是事件委托,以及如何应用它来改进我们的代码。
什么是事件委托
事件委托是一种设计模式,它利用了事件冒泡的机制。当一个元素上的事件被触发时,它会向上冒泡传递至父级元素,直至最顶层的文
展开说说
事件委托是建立在事件冒泡机制之上的,冒泡是指事件从触发事件的元素开始,逐级向上触发所有上级元素的过程。
接下来,让我们欢迎千锋虎哥为我们表演一个胸口碎大石。见他气沉丹田后,发出一声咆哮,只听咔嚓一声...
是的,编不下去了!
力量传递到第一层瓦片时,第二层、第三层,以及第n层依次受到力量的作用,就像事件冒泡的过程一样。
接着看这个图
在鼠标点击div1时,力量会逐级传导到div2上,然后继续传导到div3,一直延伸至body,最终到达window。只要在对应的元素上设置了点击事件,该事件就会被触发,并且按照冒泡的顺序依次传递至父级元素
那么好,需求来了,现在需要div点击的时候,缩小自己的宽和高,每次缩小到自己的百分之90,看效果
第一个想到的方案是为每个元素添加点击事件,并需要阻止事件冒泡(自行查阅阻止冒泡)。
const div1 = document.querySelector('.div1')
const div2 = document.querySelector('.div2')
const div3 = document.querySelector('.div3')
div1.addEventListener('click', (e) => {
div1.style.width = parseInt(window.getComputedStyle(div1).width) * 0.9 + 'px'
div1.style.height = parseInt(window.getComputedStyle(div1).height) * 0.9 + 'px'
e.stopPropagation() //阻止冒泡
})
div2.addEventListener('click', (e) => {
div2.style.width = parseInt(window.getComputedStyle(div2).width) * 0.9 + 'px'
div2.style.height = parseInt(window.getComputedStyle(div2).height) * 0.9 + 'px'
e.stopPropagation() //阻止冒泡
})
div3.addEventListener('click', (e) => {
div3.style.width = parseInt(window.getComputedStyle(div3).width) * 0.9 + 'px'
div3.style.height = parseInt(window.getComputedStyle(div3).height) * 0.9 + 'px'
e.stopPropagation() //阻止冒泡
})
这代码看着挺冗余啊,再提炼提炼,既然每个div触发的事件都相同,能不能使用一个函数处理呢,可以的,接着看
const div1 = document.querySelector('.div1')
const div2 = document.querySelector('.div2')
const div3 = document.querySelector('.div3')
function changeSize(e) {
e.target.style.width = parseInt(window.getComputedStyle(e.target).width) * 0.9 + 'px'
e.target.style.height = parseInt(window.getComputedStyle(e.target).height) * 0.9 + 'px'
e.stopPropagation()
}
div1.addEventListener('click',changeSize)
div2.addEventListener('click',changeSize)
div3.addEventListener('click',changeSize)
确实简洁了不少。顺便说说e.target,指哪个元素触发了事件,e.target就是哪个元素对象
那能不能再简洁一点呢,既然有了冒泡。那div1、2点击的时候,冒泡到div3上,只给div3做个点击事件,是不是也行?来看看代码
const div3 = document.querySelector('.div3')
div3.addEventListener('click', (e) => {
e.target.style.width = parseInt(window.getComputedStyle(e.target).width) * 0.9 + 'px'
e.target.style.height = parseInt(window.getComputedStyle(e.target).height) * 0.9 + 'px'
e.stopPropagation()
})
是不是x格一下子就高上来了,这种操作就叫做事件委托,把div1、div2事件委托给div3处理
这是工作摸鱼、提升效率之利器
事件委托的优缺点
优点:
● 减少事件处理程序的数量:通过将事件绑定在父元素上,可以避免给每个子元素都添加事件处理程序。这在处理大量元素时可以显著减少代码的复杂性和维护成本。
● 动态添加元素支持:对于后续动态添加的子元素,无需单独为它们添加事件处理程序,因为事件委托是基于父元素的,新添加的元素也会受到委托的处理。
● 内存和性能优化:事件委托利用事件冒泡的特性,将事件处理放在父元素上,避免了在每个子元素上都绑定事件,从而节省内存和提高性能。
● 方便绑定动态元素:当页面中存在大量元素时,事件委托可以方便地处理动态添加的元素,无需为新元素单独添加事件监听。
缺点:
● 事件冒泡带来的潜在问题:由于事件冒泡的特性,事件委托可能导致事件在父元素上被多次触发,这可能会影响性能和产生不良影响。为了避免这个问题,需要在事件处理程序中正确判断事件源。
● 不适用于所有情况:并非所有事件都适合使用事件委托。例如,如果需要在不同阶层的元素上绑定不同的事件处理程序,或者需要对事件进行捕获阶段的处理,事件委托可能无法满足需求。
● 事件目标确定:在事件委托中,需要通过事件对象的target属性来确定真正的事件目标,这可能会涉及到一些复杂的逻辑。
总结:
总体来说,事件委托是一种非常有用的技术,特别适合处理大量元素的事件处理。它可以提高代码效率、减少内存占用,并且方便处理动态添加的元素。然而,需要注意避免潜在的问题,以确保事件委托的正确使用。