事件委托

Posted antyhouse

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事件委托相关的知识,希望对你有一定的参考价值。

认真看,每个人都可以看懂的-_-也可以结合js高级程序设计第三版一起看哦~

什么是事件委托--官方解释
对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。例如,click 事件会一直冒泡到 document 层次。也就是说,我们可以为整个页面指定一个 onclick 事件处理程序,而不必给每个可单击的元素分别添加事件处理程序

下面一句话很重要!很重要!很重要!
只要进行了点击就是会有捕获阶段->目标阶段->冒泡阶段三个阶段,和你在哪个阶段去添加事件处理程序无关
意思就是只要有点击,都会有着三个阶段,不管是有没有绑定事件

事件委托主要是利用了冒泡,假如我用鼠标点击了box2,第三阶段是冒泡阶段 ,会从 id为box2的li标签-->ul-->body-->html-->window
说明我不管是点击box1,box2,还是box3 都会经历 boxn -->ul-->body-->html-->window的过程,所以我们可以在li的上一级ul添加一个事件处理程序,因为event里面会有一个target我们获取获取到目标元素
event.target 和 event.currentTarget有什么区别?
event.target表示的目标元素,事件捕获到最底层的那个元素,event.currentTarget表示的是监听元素,这里指的就是addEventListener监听的那个元素

   <ul id="mylinks">
        <li id="box1">box1</li>
        <li id="box2">box2</li>
        <li id="box3">box3</li>
    </ul>

1为什么需要事件委托?
如果我点击父元素底下很多个li标签,每个点击做不同的操作,那么结果就会有数不
清的代码用于添加事件处理程序

    <ul id="mylinks">
        <li id="box1">box1</li>
        <li id="box2">box2</li>
        <li id="box3">box3</li>
    </ul>
</head>
<body>
    <script>
        // 因为冒泡事件是逐级向上冒泡的 所以在最高级去添加一个事件就好 dom2写法
        //需求:点击每一个做不同的操作,如果这里有无数个li 要写100种写法
        var box1 = document.getElementById('box1')
        var box2 = document.getElementById('box2')
        var box3 = document.getElementById('box3')
        box1.addEventListener('click', ()=> {
            console.log('box1');
        })
        box2.addEventListener('click', ()=> {
            console.log('box2');
        })
        box3.addEventListener('click', ()=> {
            console.log('box3');
        })
    </script>

如果我用事件委托

   <ul id="mylinks">
        <li id="box1">box1</li>
        <li id="box2">box2</li>
        <li id="box3">box3</li>
    </ul>
</head>
<body>
    <script>
        var bigBox = document.getElementById('mylinks')
        bigBox.addEventListener('click', (event)=> {
            var target = event.target
            switch (target.id) {
                case 'box1':
                    document.title = 'box1'
                    console.log(document.title);    
                    break;
                case 'box2':
                    document.title = 'box2'
                    console.log(document.title);    
                    break;
                case 'box3':
                    document.title = 'box3'
                    console.log(document.title);    
                    break;
            }            
        })

在js高级程序设计中是这样写的

 <ul id="mylinks">
        <li id="box1">box1</li>
        <li id="box2">box2</li>
        <li id="box3">box3</li>
    </ul>
</head>
<body>
    <script>
          <ul id="mylinks">
        <li id="box1">box1</li>
        <li id="box2">box2</li>
        <li id="box3">box3</li>
    </ul>
</head>
<body>
    <script>   
        // 因为冒泡事件是逐级向上冒泡的 所以在最高级去添加一个事件就好 dom2写法
        //需求:点击每一个做不同的操作,如果这里有无数个li 要写100种写法、
        let EventUtil = {
            getEvent: function(event){ 
                return event ? event : window.event; 
            },
            getTarget: function(event){ 
                return event.target || event.srcElement; 
            }
        }
        var bigBox = document.getElementById('mylinks')
        bigBox.addEventListener('click', (event)=> {
            event = EventUtil.getEvent(event); 
            var target = EventUtil.getTarget(event);  
            var target = event.target
            switch (target.id) {
                case 'box1':
                    document.title = 'box1'
                    console.log(document.title);    
                    break;
                case 'box2':
                    document.title = 'box2'
                    console.log(document.title);    
                    break;
                case 'box3':
                    document.title = 'box3'
                    console.log(document.title);    
                    break;
            }            
        })
</script>

书上有提到--IE 中 event 对象的全部信息和方法 DOM 对象中都有
这里是采用的兼容写法---主要是因为获取这个event和event.target的方式不一样

2.事件委托的好处
? document 对象很快就可以访问,而且可以在页面生命周期的任何时点上为它添加事件处理程序(无需等待 DOMContentLoaded 或 load 事件)。换句话说,只要可单击的元素呈现在页面上,就可以立即具备适当的功能。
? 在页面中设置事件处理程序所需的时间更少。只添加一个事件处理程序所需的 DOM 引用更少,所花的时间也更少。
? 整个页面占用的内存空间更少,能够提升整体性能。

以上是关于事件委托的主要内容,如果未能解决你的问题,请参考以下文章

jQuery代码优化:事件委托

C#事件

Javascript中的事件委托机制

js中的事件委托/代理

编写高质量代码改善C#程序的157个建议——建议137:委托和事件类型应添加上级后缀

事件委托