美文网首页
DOM事件与事件委托

DOM事件与事件委托

作者: fanison | 来源:发表于2020-06-28 22:45 被阅读0次

    事件流

    DOM 事件流分为三个阶段:捕获阶段、目标阶段、冒泡阶段。先调用捕获阶段的处理函数,其次调用目标阶段的处理函数,最后调用冒泡阶段的处理函数。

    • 事件捕获: 从外向内找监听函数
    • 事件冒泡:从内向外找监听函数

    .addEventListener() 绑定事件

    将指定的监听器注册到 EventTarget上,当该对象触发指定的事件时,指定的回调函数就会被执行。
    target.addEventListener(type, listener, useCapture);

    type: 监听事件类型
    listener:实现了 EventListener接口的对象,或是一个函数
    useCapture:默认为 false,处于冒泡阶段;为 true时,处于捕获阶段

    取消冒泡

    e.stopPropagation 可中断冒泡

    不可取消冒泡

    • 有些事件不可取消冒泡
      例如scroll event
      Bubbles:该事件是否冒泡
      Cancelable:是否可以取消冒泡

    禁用滚动

    // 阻止滚轮滚动
    x.addEventListener('wheel', (e)=>{
      e.preventDefault()
    })
    // 滚动条可以滚动,使用CSS隐藏滚动条
    .element::-webkit-scrollbar { width: 0 !important }
    // 取消触屏默认动作
    x.addEventListener('touchStart', (e)=>{
      e.preventDefault()
    })
    

    自定义事件

      <div id=div1>
        <button id=button1>点击触发自定义事件     
        </button>
      </div>
    
    button1.addEventListener('click', ()=>{
      const event = new CustomEvent("new", {"detail":{name:'new', age: 18}})      // 定义事件
      button1.dispatchEvent(event)  // 触发事件
    })
    
    button1.addEventListener('new', (e)=>{
      console.log('new')
      console.log(e)
    })
    

    target、currentTarget

    • 区别:
      e.target 用户操作的元素
      e.currentTarget 程序员监听的元素
    <div>
      <span>文字</span>
    </div>
    

    用户点击文字, e.target就是 span,e.currentTarget 就是 div

    事件委托

    1. 简易版
      div > button
    div.addEventListener('click',function(e){
      if(e.target.tagName.toLowerCase() === 'button'){
        fn() //执行某个函数
      }
    })
    

    封装on函数实现
    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)
        }
      })
    }
    

    2、高级版
    div > button > span
    如果用户点击的是button 里面的 span,就没法触发fn;
    思路是点击 span 后,递归遍历 span 的祖先元素看看其中有没有 div 中的button

    function on(eventType,element,selector, fn) {
      if(!(element instanceof Element)){
        element = document.querySelector(element)
      }
      element.addEventListener(eventType, e => {
        let el = e.target
        while (!el.matches(selector)) {
          if (element === el) {
            el = null
            break
          }
          el = el.parentNode
        }
        el && fn.call(el, e, el)
      })
      return element
    }
    

    相关文章

      网友评论

          本文标题:DOM事件与事件委托

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