《dom的事件委托》

128 阅读2分钟

dom的事件委托

  • 如果我们有很多元素以类似的方式处理,那么我们不是为每个元素分配一个处理程序 - 我们将一个处理程序放在它们的共同祖先上。这是事件委托
  1. 优点:可以减少内存占用,减少事件注册
<ul class=list>
    <li></li>
    <li></li>
    <li></li>
    ...    
    <li>n</li>
</ul
  1. 可以实现当新增子对象时无需再次对其绑定(动态绑定事件)

- 怎么阻止默认动作?

e.preventDefault();

e.returnValue;

$form.on('submit',(e)=>{
            //阻止默认事件
           // e.preventDefault();//适合普通游览器 如阻止链接跳转和表单提交
           //e.returnValue;//适用于ie6,7,8
           return false;//无兼容
          )};

- 怎么阻止事件冒泡?

标准写法:利用事件对象里的stopPropagation()方法
非标准写法(IE6-8)利用事件对象cancelBubble属性

 document.getElementById('box1').onclick= function(e){
                var ev = e || window.event
                //阻止冒泡
                //ev.stopPropagation()
                ev.cancelBubble = true;
                this.style.backgroundColor = 'pink'
            }

target和currentTarget

//当用户点击文字的时候
    <div>                   //e.currentTarget 就是div
        <span>文字</span>   //e.target就是span
    </div>

e.target: 用户操作的元素
e.currentTarget: 程序员监听的元素
thise.currentTarget, 是不推荐的用法,因为this指向不确定

  • 实际开发过程中可能会遇到以下两种情形:
  1. 为了满足同时监听多个元素。
  2. 需要监听的元素还不存在
    此时,可以对这些元素的祖先进行监听,这样就可以节省内存和动态的监听元素
  • 示例1
  • 要给100个按钮添加点击事件,我们先监听这100个按钮的祖先,等冒泡的时候判断target是不是这100按钮的其中一个。 饥人谷JS Bin (jirengu.com)
div1.addEventListener('click',(e)=>{
  const t = e.target
  if(t.tagName.toLowerCase() === 'button'){
    console.log('button 被点击了!')
  }
})
  • 当需要操作的元素一开始不存在时,无法写在js中对该元素进行监听,通过事件委托一样可以实现。代码如下 饥人谷JS Bin (jirengu.com)
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 被点击了!')
  }
})
  • 这样做的优点是
  1. 省内存
  2. 可以监听动态元素

封装事件委托

饥人谷JS Bin (jirengu.com)

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

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

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)
    }
  })
}