美文网首页
2020-11-24

2020-11-24

作者: 二荣xxx | 来源:发表于2020-11-24 22:10 被阅读0次

事件委托

事件委托:通俗地来讲,就是把一个元素响应事件(click、keydown......)的函数委托到另一个元素

这里引用一下别人的话:
一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数。

一、省监听数(内存)

如果要给100个按钮添加点击事件,我们只需要用事件委托监听这100个按钮的祖先,等冒泡的时候判断target是不是这100个按钮中的一个

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<div id="div1">
  <button data-id="1">click 1</button>
  <button>click 2</button>
  <button>click 3</button>
  //...此处省略96行
  <button>click 100</button>
</div>
</body>
</html>
div1.addEventListener('click',(e)=>{
  const t=e.target
  if(t.tagName.toLowerCase()==='button'){ //判断被操作的元素是否为button
       console.log('button被点击了+t.textContent')
      console.log('button data-id是' + t.dataset.id) //dataset.id用来获取data-id的值
    }
})

二、可监听动态元素

如果有一个button在一秒钟之后出现,那我们监听改元素的祖先,等点击的时候看看是不是我想要监听的元素即可

setTimeout(() => {
  const button = document.createElement('button')
  button.textContent = 'click 1'
  div1.appendChild(button)
}, 1000)

div1.addEventListener('click', (e) => {
  const t = e.target
  if (t.tagName.toLowerCase() === 'button') {
    console.log('button 被click')
  }
})

封装事件委托

思考:
写出这样一个函数on('click','#testDiv','li',fn),当用户点击#testDiv里的li元素时,调用fn函数,要求用到事件委托。
答案一(常规)

setTimeout(() => {
  const button = document.createElement('button')
  button.textContent = 'click 1'
  div1.appendChild(button)
}, 1000)

//在div1上做事件委托看button有没有被点击
on('click', '#div1', 'button', () => {
  console.log('button 被点击了')
})

//输入(事件类型,元素,选择器/准备匹配什么元素,回调函数)
function on(eventType, element, selector, fn) {
  if (!(element instanceof Element)) {
    element = document.querySelector(element)
  }
  element.addEventListener(eventType, (e) => {
    const t = e.target
      //判断一个元素是否满足一个选择器
    if (t.matches(selector)) {
      fn(e)
    }
  })
}

答案二(特殊)
如果button里面还有个span,span的内容是chick 1,点击chick 1 实际操作的元素是span,就不能通过button被点击了。
要用递归判断,如果当前元素不匹配button,就向自己的祖辈寻找,如果祖辈里有button就说明点击了button。

setTimeout(() => {
  const button = document.createElement('button')
  const span = document.createElement('span')
  span.textContent = 'click 1'
  button.appendChild(span)
  div1.appendChild(button)
  
}, 1000)

//在div1上做事件委托看button有没有被点击
on('click', '#div1', 'button', () => {
  console.log('button 被点击了')
})

//输入(事件类型,元素,选择器/准备匹配什么元素,回调函数)
function on(eventType, element, selector, fn) {
  if (!(element instanceof Element)) {
    element = document.querySelector(element)
  }
  element.addEventListener(eventType, e => {
    let el = e.target
      //看看被操作的元素是否符合button
    while (!el.matches(selector)) {
      //如果在找的时候一直找到了div1,就认为找不到了,判定为空,跳出
      if (element === el) {
        el = null
        break
      }
      //不符合就让这个元素等于父元素
      el = el.parentNode
    }
    //如果找到了就调用fn,第一个参数传e,第二个传匹配到的元素
    el && fn.call(el, e, el)
  })
  return element
}

-------以上 代码引用自语雀---釉纸糖

相关文章

  • 周二 2020-11-24 23:20 - 06:37 雨 09

    2020-11-24 上午超纲完成任务,然后下午直接爆炸崩了个惨周二 2020-11-24 23:20 - 06:...

  • 30个主题(结2020-11-24

    有话(结2020-11-24[https://www.jianshu.com/p/ffa64350e89d] 生活...

  • 更新日记

    2020-11-24 新增收支明细 2020-10-22 新增销售订单的订单编号 新增采购订单的订单编号 新增交易...

  • 2020-11-24自我观察记录

    【2020-11-24日精进 第189天/1825】表现:8分 体验: 1.昨天感觉在混沌中,无获得感,也分不清...

  • 2020-11-24

    中原焦点团队祝澜 1063天 2020-11-24 今天早上,穿上了羽绒服,敏感的鼻炎稍微好了一些。 中午,学...

  • 致人类书:(44)慈悲心会将人类团结在一起

    鸢尾天空2020-11-24 16:32:06 日安,我们是阿柯图-瑞恩! 我们正在倾听人类心灵的声音。我们对于那...

  • 如何培养孩子的自我价值感

    中原焦点团队 成长分享869天 2020-11-24 生活中,一些孩子本来自身条件很好,但是却很自卑、不自信,没有...

  • 上班日记 Day87

    2020-11-24 实地调研发现场景已不如想象了,应如何对产品改造? 暂时没想法,留个坑 提示语怎么写合适 新人...

  • 践行五个一•打卡41天

    2020-11-24 【周岳五个一】#百日践行100/41天 【健身之志】 今日早起打卡第41天 送娃上学,陪娃...

  • 2020-11-24

    2020-11-24 姓名 :曹静杰 企业名称 : 辽宁辽阳丛迪服装有限公司 组别 388期 反省1组 志工529...

网友评论

      本文标题:2020-11-24

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