6-7 JS编程接口(DOM事件、事件委托、封装事件委托)

DOM事件与事件委托

3.自定义事件

  • 浏览器自带事件
    一共100多种时间,列表在MDN上:事件参考
  • 提问
    开发者能不能在自带事件之外,自定义一个事件
    答:可以
    在这里插入图片描述
  • 自定义事件
    创建一个 名称为 frank ,可以自动冒泡,但是不能阻止冒泡的自定义事件
<div id=div1>
   <button id=button1>点击触发 frank 事件     
   </button>
</div>
button1.addEventListener('click', () => { //被点击时触发一个自定义事件
  const event = new CustomEvent('frank', {
      detail: {name: 'frank',age: 18},
      bubbles: true, //可以冒泡,也就是可以通过监听div1获得事件信息
      cancelable: false //不能阻止冒泡
    }) //创建一个自定义事件,告诉事件名和详细信息
  button1.dispatchEvent(event) //button1就触发事件
})

div1.addEventListener('frank', (e) => {
  console.log('frank事件触发了')
  console.log(e.detail)
})

3.事件委托

  • 委托:委托中介做本该自己做的事情
  • 事件委托:委托一个元素帮我监听我本该监听的东西
  • 场景一
    1.你要给100个按钮添加点击事件,咋办?
    答:监听这100个按钮的祖先,等冒泡的时候判断 target 是不是这 100 个按钮中的一个
  • 场景二
    你要监听目前不存在的元素的点击事件,咋办?
    答:监听祖先,等点击的时候看看是不是我想要监听的元素即可
  • 优点
    1.省监听数(内存)
    2.可以监听动态元素:后面才会出现的元素

3.1 场景一代码

  • 将监听绑在div1上,判断以下被点击的是谁即可
  • tagName 属性返回元素的标签名。
  • toLowerCase() 方法用于把字符串转换为小写。
  • 如何知道点击的是 div1 中的哪一个button?
    答:通过被点击的元素
  • data-id 和 id的区别
    1.id是选择器
    2.data-id只是行内存放数据的一个标签
    3.同时在HTML5 中增加了一项新功能是 自定义数据属性 ,也就是 data-* 自定义属性。
    4.在HTML5中我们可以使用以 data- 为前缀来设置我们需要的自定义属性,来进行一些数据的存放。
  • dataset 可以获取以data开头的属性的值
<div id="div1">
  <span>span1</span>
  <button data-id='1'>click1</button>
  <button data-id='2'>click2</button>
  <button data-id='3'>click3</button>
</div>
div1.addEventListener('click',(e)=>{
  const t = e.target //被用户点击的元素
  if(t.tagName.toLowerCase()==='button'){//如果被点击的元素是button,说明是button元素中的一个
    console.log('button 被点击了')
//     console.log('buuton内容是'+t.textContent)
    console.log('button data-id是'+t.dataset.id)
  }
})

3.2 场景二代码

  • 一秒之后出现button
  • 动态元素
<div id="div1">
</div>
setTimeout(()=>{
  const button = document.createElement('button')
  button.textContent = 'click1'
  div1.appendChild(button)
},1000)

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

4.封装事件委托

  • 上面是针对特定场景的事件委托
  • 写一个函数,用户只需要用这个on事件,就可以在 div1上面做事件委托,来看button有没有被点击
  • 输入:接收四个参数,事件类型、元素(被委托的)、选择器(准备匹配什么元素)、函数(点击的时候被调用的)
  • matches 用来判断一个元素是否满足一个选择器(比如:一个元素是不是 li、button)
  • 这个函数就是一个封装好的事件委托函数,只要用这个 on,就可以实现事件委托
<div id="div1">
</div>
setTimeout(()=>{
  const button = document.createElement('button')
  button.textContent = 'click1'
  div1.appendChild(button)
},1000)

on('click','#div1','button',()=>{
  console.log('button 被点击了')
})

function on(eventType,element,selector,fn){
  if(!(element instanceof Element)){
    element = document.querySelector(element)
  }//如果element不是元素,则寻找这个元素
  element.addEventListener(eventType,(e)=>{
    const t = e.target
    if(t.matches(selector)){
      fn(e)
    }
  })
}

5.面试:什么是事件委托

  • 给元素添加一个监听,然后看当前的 target 是否满足 selector,如果满足就调用函数,如果不满足就放过
  • 但这个方法是有问题的
    1.如果文字外面有个span,那么用户点击的就是 span
    2.那么我们在匹配的时候 span 就不匹配 button,无法实现事件监听
    3.解决:使用递归判断,如果当前元素不匹配,就依次往外走,判断target、target的爸爸、target的爷爷,一直到div1停止
<div id="div1">
 <button>
   <span>文字</span>
 </button>
</div> 

6.JS支持事件吗?


  • 支持,也不支持。本节课讲的是 DOM 事件不属于 JS 的功能,术语浏览器提供的 DOM功能
    JS是浏览器的功能之一,DOM事件又是浏览器的另一个功能
    JS只是调用了 DOM 提供的 addEventListener 这个API而已
  • 能否手写出一个 JS事件系统
    用一个队列,后面在思考
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值