原生js怎么实现jquery .on( events, selector, handler )委派事件??

jquery中如下可以实现事件委派,动态添加的tr也会触发该事件

$( "#dataTable tbody" ).on( "click", "tr", function() {
  console.log( $( this ).text() );
});

在原生js中该怎么实现该功能?

阅读 2.3k
2 个回答
function eventDelegate (e,targetSelector,fn) {
    // 兼容性处
    let event = e || window.event;

    // 获取到目标阶段指向的元素
    let target = event.target || event.srcElement;

    // 获取到代理事件的函数
    let currentTarget = event.currentTarget;

    // 处理 matches 的兼容性
    if (!Element.prototype.matches) {
      Element.prototype.matches =
        Element.prototype.matchesSelector ||
        Element.prototype.mozMatchesSelector ||
        Element.prototype.msMatchesSelector ||
        Element.prototype.oMatchesSelector ||
        Element.prototype.webkitMatchesSelector ||
        function(s) {
          let matches = (this.document || this.ownerDocument).querySelectorAll(s),
            i = matches.length;
          while (--i >= 0 && matches.item(i) !== this) {}
          return i > -1;
        };
    }

    // 遍历外层并且匹配
    while (target !== currentTarget) {
      // 判断是否匹配到我们所需要的元素上
      if (target.matches(targetSelector)) {
        let sTarget = target;
        // 执行绑定的函数,注意 this
        fn.call(sTarget, Array.prototype.slice.call(arguments))
      }

      target = target.parentNode;
    }

上面这位大佬的方法很标注,很严禁,但不适合小白理解:

首先要明白委托是什么意思:委托并没有给子元素绑定事件,点击子元素的时候根据事件冒泡的原理,触发了body上绑定的事件,这个方法是能获取到点击的子元素的事件对象的,这个比较简单;
难点其实是另一个问题,子元素dom结构通常不止1层,那么如何让事件对象是我们想要那个,一般要的是子元素最外层的元素,下面一个栗子可以告诉你怎么获取你想要的父节点的事件对象:

var a=document.getElementById('content_left');//以百度搜索结果列表为例
a.onclick = function(ev){//这个ev是你点击的那个子元素的子元素
            var ev = ev || window.event;
            var target = ev.target || ev.srcElement;
        while(target!=a){//在非父节点中寻找最外层dom
            console.log(target.className)
                        if(target.className == 'c-abstract'){//c-abstract是我想要的每一项列表的最外层
                            target.style.background = "#eee";
                break;
                    }
        target=target.parentNode;//通过while,逐级寻找父节点
     }
};
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题