首先展现我们的操作页面的搭建,我们从其触发顺序来得知事件捕获和事件冒泡的原理。

<div>

   <div id="a">

      <div id="b">

         <div id="c"></div>

      </div>

   </div>

</div>

然后分别对#a,#b,#c绑定click事件

<script>

   document.getElementById('a').addEventListener('click',function () {

      console.log(1)

   },true);

   document.getElementById('b').addEventListener('click',function () {

      console.log(2)

   },true);

   document.getElementById('c').addEventListener('click',function () {

      console.log(3)

   },true);

 

   document.getElementById('a').addEventListener('click',function () {

      console.log(6)

   },false);

   document.getElementById('b').addEventListener('click',function () {

      console.log(5)

   },false);

   document.getElementById('c').addEventListener('click',function () {

      console.log(4)

   },false);

</script>

事件代理详解

点击c

输出:1->2->3->4->5->6

true的时候,属于事件捕获:从外到里触发;

事件捕获都是从window->document->html->body->div#a->div#b->div#c

false的时候,属于事件冒泡:从里到外触发

 

事件对象:

document.getElementById("a").addEventListener('click',function (e) {

   console.log(e);

})

浏览器在触发click事件时包装一个对象,里面是事件的信息。从回调中返回。

 

事件委托:

事件代理详解

<body>

   <ul id="ul">

      <li>吃饭</li>

      <li>睡觉</li>

      <li>打球</li>

     <li>洗澡</li>

   </ul>

 

   <input type="'text" id="input">

   <button id="btn">add</button>

<script>

   var list = document.querySelectorAll('#ul li');

   console.log(list);

   for(var i = 0,len = list.length;i < len;i++){

      list[i].addEventListener('click',function () {

      alert(this.innerHTML)

     },false)

   }

 

   document.querySelector('#btn').addEventListener('click',function () {

      var text = document.querySelector('#input').value;

      var li = document.createElement('li')

      li.innerHTML = text;

      li.addEventListener('click',function () {

         alert(this.innerHTML)

      })

      document.querySelector('#ul').appendChild(li);

   },false)

</script>

</body>

在我添加的这个li中,还需要给他绑定事件,如果有成百上千的要添加,就太繁琐了吧。

由此就有事件委托。

 

jQuery实现事件代理:

 

$('#ul').click('#ul li',function () {

   alert(1);

})

 

$('#btn').click(function () {

   $('#ul').append('<li>adasda</li>')

})

 

这样动态添加的li是直接绑定着事件的。

 

我们来看看其实现:

document.querySelector('#ul').addEventListener('click',function (e) {

   console.log(e.target);

})

//<li>洗澡</li>

arget就是实际捕获的元素。

事件有三个阶段:捕获,目标,冒泡。

 

实现一个on,来实现事件代理

 

 

function on(ele, type, selector,fn) {

   if(fn === undefined){

      fn = selector;//表示selector没有传,比如on(ele,'click',function(){}),就把selector部分直接赋值给fn代替

      selector = null;

   }

   ele.addEventListener(type,function (e) {

      if(selector){//如果true,就需要事件代理

         if(e.target.matches(selector)) fn.call(e.target,e);//e.target和selector去匹配,匹配到的话,就去执行fn。把e.target作为this传给fn,然后把事件对象e传递过去。这就完成了事件代理

         return;

      }

      fn.call(e.currentTarget,e);

      // fn(e);

   })

}

 

on(document.querySelector('#ul'),'click','li',function (e) {

   console.log(this);

})

 

// // 假如不传li,this的指向就是window,所以对上面进行修改

// on(document.querySelector('#ul'),'click',function (e) {

// console.log(this);

// })

 

 

 

 

 

 

 

 

 

 

相关文章:

  • 2022-12-23
  • 2021-11-29
  • 2022-12-23
  • 2022-12-23
  • 2022-02-02
猜你喜欢
  • 2021-06-05
  • 2022-01-21
  • 2022-12-23
  • 2022-12-23
  • 2021-11-25
相关资源
相似解决方案