欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

理解JavaScript中的事件代理原理

最编程 2024-08-07 14:48:55
...

事件绑定

直接在dom元素上绑定一个事件,这是最简单的方法,也是最不好的方法,比如在多个js文件中有可能会覆盖掉之前的文件

var ul = document.getElementById('ul')
console.log(ul)
ul.onclick = function() {
    console.log('click 事件绑定成功') // 并不会触发
}
ul.onclick = function(){
  console.log('click2事件绑定成功')
}

事件监听

事件监听实现的功能和直接绑定差不多,但是新增了一个特点。那就是无论监听次,都不会覆盖掉前面的监听事件。本质原因是监听事件每次都会生产一个全新的匿名函数,和前面的函数完全不同,自然不会覆盖。

事件冒泡和捕获

事件捕获:当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。

事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。

事件冒泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。

阻止事件冒泡的的方法

  1. e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)
  2. 我们也能通过改变addEventListener的第三个参数改变事件的执行顺序。(false为冒泡阶段执行,true为捕获阶段执行,默认为false)

事件委托

通俗的来讲就是把一个元素的响应事件函数,委托到另一个元素。
举个例子,就是有一堆li标签,需要给每一个li标签添加click事件,但是如果有几万个li标签,每个标签都显式地去添加事件函数,会影响性能。这里有一个解决方案就是把li的事件函数,委托到它的上一层父级ul标签去(假如它的父级是ul)

<body>
    <ul id='list'>
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
        <li>item 4</li>
    </ul>
    
</body>
<script>
    document.getElementById('list').addEventListener('click', function(e) {
        var event = e || window.event
        var target = e.target || event.srcElement
        var nodeNameTemp = target.nodeName.toLocaleLowerCase()
        if(target.nodeName.toLocaleLowerCase() === 'li') {
            console.log('this content is :', target.innerHTML);
        }
    })
</script>

这里首先在父级ul上定义一个事件监听,变量event是回调函数获取到的事件对象,target变量是#list元素下被点击的li目标元素,通过这个target变量,我们可以获取一些例如nodeName和id这种属性。然后就是通过属性判断是否是点击的li的一些逻辑。

一些启发,在纯js编程中使用代理

dom事件的处理机制是依赖于浏览器的事件冒泡机制为dom添加事件按委托,同样的我们在js编程中也可以使用同类型的代理模式创建对象来操作目标对象,来达到隐藏一些对象的目的。

 var delegate = function(client, clientMethod) {
        return function() {
            clientMethod.apply(client, arguments)
        }
    }

    var classA = function(){
        var color = 'red'

        return {
            getColor: function() {
                console.log('color: ', color)
            },
            setColor: function(_color){
                color = _color
            }
        }
    }

    var tempA = new classA()
    tempA.getColor()
    tempA.setColor('green')
    tempA.getColor()
    console.log('delegate start------')
    var delegateTemp = delegate(tempA, tempA.setColor)
    delegateTemp('blue')
    console.log("delegete finish");
    tempA.getColor();