多层元素实现的委托

作者: issac_宝华 | 来源:发表于2017-12-12 23:44 被阅读0次
    image

    前言

    很久没有在简书上写blog,都在github上写了,看有点时间就搬运一下
    关于事件委托的概念和原理就不多说,自行Google。

    二层元素实现的委托

    二层元素实现的委托是我自己定义的名称,具体是如下的场景

    <div id="tab">
        <a href="javascript:;" title="left">left</dl>
        <a href="javascript:;" title="right">right</dl>
    </div>
    

    然后将事件绑定在id="tab"元素上。这样的场景也是在比较多的,高程对事件委托的解析也是用以上差不多的代码解析的,具体实现是这样的:
    先是将事件绑定在id="tab"元素上,点击是判断title,title === ‘left’时触发left的逻辑,否则触发right的逻辑

    document.querySelector('#tab')
    .addEventListener('touchstart', e => {
       const target = e.target;
       if(target.title === 'left') {
           // left的逻辑代码
       } else {
           // right的逻辑代码
       }
    }, false);
    

    这样的代码乍看之下貌似没有问题,但是,加入是下面的html代码就会出现bug:

    <div id="tab">
      <a href="javascript:;" title="left"><img src="left_icon.png"> left</a>
      <a href="javascript:;" title="right"><img src="right_icon.png"> right</a>
    </div>
    

    当点击a便签的图标,就会出现bug,只要是点击中图标,无论是点击left还是right都会是触发right的逻辑,
    为什么?因为点击中icon的话,e.target是img便签,而不是a便签,而img并没有title,如果你说可以给img便签也可以添加title,但这不是一个之便不治本的解决方案吗?加入a便签内有更多的后代元素怎么办?全都添加title吗?明显不现实。

    event.path属性实现委托

    使用console.log(e)点path属性,你可以卡到path是一个数组

    image

    升序正好是冒泡顺序,正好可以利用这个顺序实现多层元素的事件委托。

    document.querySelector('#tab')
    .addEventListener('touchstart', e => {
      const path = e.path;
      for (let index = 0; index < path.length; index++) {
        const element = path[index];
        if(element.title === 'left') {
          // left
          break;
        } else if(element.title === 'right') {
          // right
          break;
        }
      }
    }, false);
    

    event.composedPath()

    虽说以上代码已经可以实现多级元素的事件委托,但是不幸的是path的兼容性是比较差[捂脸]

    image

    看上面的引用,可以知道path并非标准的,而composedPath才是标准的,但也是比较新的,换言之,兼容性也不会有多好,但pathcomposedPath一起使用,兼容必然会更高。

    document.querySelector('#tab')
    .addEventListener('touchstart', e => {
      const path = e.path || e.composedPath();
      for (let index = 0; index < path.length; index++) {
        const element = path[index];
        if(element.title === 'left') {
          // left
          break;
        } else if(element.title === 'right') {
          // right
          break;
        }
      }
    }, false);
    

    小结

    以上实现委托的方法是我自己自行意淫的,是不是主流实现方法?我还还没有去验证,先留个坑,谁那么巧合看到了我的文章,有更好的想法,或者主流方法实现,请不吝赐教。

    导航

    相关文章

      网友评论

        本文标题:多层元素实现的委托

        本文链接:https://www.haomeiwen.com/subject/vlmoixtx.html