事件委托解决JS/jQuery获取不到动态添加的元素节点的问题

通过【事件委托】解决JS/jQuery获取不到动态添加的元素节点的问题

发现问题:

本来想通过name获取动态遍历添加的节点元素,对其使用事件监听(addEventListener)绑定事件;但是发现不论通过js的 document.getElementsByName 还是通过jquery的$(‘name=“node”’) 都获取不到元素节点

插入一个小知识点:
特别误导我的是控制台打印出来是一个空数组 [],但是旁边有一个小箭头点开后又会出现节点会让我误以为获取到了节点;其实是因为点击展开时候又去读了内存,下图详细描述
在这里插入图片描述

解决过程:

上网查了之后发现动态加添的节点js或者jquery就是获取不到?
那只能换一种思路方法了,其实就是我们经常在前端面试中遇到的一个很熟悉的问题,但是真正的实际运用中其实很多人没用到过,或者用了其实并不知道这就是我们经常被问到的事件委托

解决方案:

  • 事件委托(事件代理):
    既然获取不到动态添加的元素,那我们总能获取到他的父亲,比如有一个列表:
<ul id="father">
		  <li name="children" value="1"></li>
		  <li name="children" value="2" ></li>
		  <li name="children" value="3" ></li>
</ul>  

li是我们动态遍历添加的,我们就可以通过获取到父元素ul绑定监听事件(addEventListener)
这时候大家肯定有疑问了我想要监听的是li 你给 ul 绑定有什么用;这个时候就又出来了一个我们经常被问到的问题,就是事件冒泡,js事件冒泡机制就是事件委托可以实现的核心原理;

  • 什么是事件冒泡呢?
    就是事件从最深的节点开始,然后逐步向上传播事件,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发。因为js事件冒泡的这个机制,就可以实现事件委托这个方法的运用;

  • addEventListener(事件监听函数):
    第二个参数是event;通过event.target就可以获取到我们真正点击的元素;

  • 事件委托实现过程:

    点击了li, 因为事件冒泡机制,冒泡到最上层 ul上, 所以进入了给ul绑定的事件监听函数addEventListener中,通过addEventListener的第二个参数event获取到当前点击的真正元素进行判断是否为li,进行下一步的项目中的业务逻辑操作,至此我们就利用事件委托解决了获取不到动态节点元素的问题,且大大优化了浏览器性能,节省了内存,不用全部遍历li元素进行事件绑定占用相当大的内存;

这样做的好处:

利用事件委托不仅可以解决js获取不到动态元素节点的问题,而且可以节省内存,如果我们通过name去获取到了100个1000个节点,然后通过遍历去给这些节点添加绑定事件,内存占用率就非常大,性能自然就差了,
但是如果我们通过事件委托,去把事件委托给父亲元素,大大的优化的性能;

一个栗子(移动端长按事件监听实现):

      let timeOutEvent;

      const node = $('#father'); // 获取父亲节点

      node.addEventListener('touchstart', function (e) { // 给父亲节点绑定事件监听函数
        // 开启定时器前先清除定时器,防止重复触发
        clearTimeout(timeOutEvent);
        // 开启延时定时器
        timeOutEvent = setTimeout(function () { // 长按的逻辑
        if ($(e.target).attr('name') === 'children') { // 判断当前所点击元素是不是你想要操作的元素
            const value = $(e.target).attr('value')
            console.log(`我长按了${value}`)
        }
        }, 300);
      });

      node.addEventListener('touchmove', function () {
        // 长按过程中,手指是不能移动的,若移动则清除定时器,中断长按逻辑
        clearTimeout(timeOutEvent);
        /* e.preventDefault() --> 若阻止默认事件,则在长按元素上滑动时,页面是不滚动的,按需求设置吧 */
      });

      node.addEventListener('touchend', function () {
        // 若手指离开屏幕时,时间小于我们设置的长按时间,则为点击事件,清除定时器,结束长按逻辑
        clearTimeout(timeOutEvent);
      });

以上内容是我工作中遇到问题>发现问题>解决问题过程中自己的理解的一个记录如有不对欢迎大家指正,这个事件委托小教程比较简单易懂,适合小白刚入职场的新人,希望你们看完此教程可以对事件委托原理的理解有所帮助,

参考

https://www.cnblogs.com/liugang-vip/p/5616484.html

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值