事件流与事件委托

事件冒泡

  <style>
      .father {
        width: 300px;
        height: 300px;
        background-color: red;
      }

      .son {
        width: 100px;
        height: 100px;
        background-color: cyan;
      }
    </style>
  </head>
  <body>
    <div class="father">
      <div class="son"></div>
    </div>

    <script>
      /* 
      1.事件冒泡 : 当触发子元素的事件的时候, 所有的父级元素‘同名事件’都会被依次触发
        元素->父元素->body->html->document->window

      2.事件委托 :
        事件委托原理 : 
      */

      //子元素
      document.querySelector('.son').onclick = function(){
        alert('我是子元素')
      }

      //父元素
      document.querySelector('.father').onclick = function(){
        alert('我是父元素')
      }

      //body
      document.body.onclick = function(){
        alert('我是body')
      }

      //html
      document.documentElement.onclick = function(){
        alert('我是html')
      }

      //document
      document.onclick = function(){
        alert('我是document')
      }

      //window
      window.onclick = function(){
        alert('我是window')
      }
    </script>
  </body>

事件委托

 <body>

    <button class="btn">点我动态新增元素</button>

    <ul>
      <li>我是1</li>
      <li>我是2</li>
      <li>我是3</li>
      <li>我是4</li>
      <li>我是5</li>
      <li>我是6</li>
    </ul>


    <script>
      /* 
      事件委托 : 给父元素注册,委托子元素处理
        事件委托原理 :  事件冒泡
        事件委托应用场景 : 
          (1)实际开发最多: 给动态新增的子元素注册事件
          (2)性能优化 : 如果所有的子元素都需要注册同名事件,只需要给父元素注册
        事件委托注意点 :
          (1)事件委托不能通过this找到子元素。 (this指向父元素)
          (2)事件委托需要通过什么属性找到子元素:  e.target
      */


      //需求:给每一个li元素注册点击事件
      let ul = document.querySelector('ul')

      //2.事件委托 : 给父元素注册事件,委托给子元素处理
      ul.onclick = function(e){
        /* this : 事件源,父元素ul
           e.target : 真正点击的子元素
        */
        alert(e.target.innerText)
        console.log(e)
      }

      /* 如果一个元素是动态新增的 : 一开始没有,页面加载后使用dom新增语法添加的 */
      document.querySelector('.btn').onclick = function(){
        let li = document.createElement('li')
        li.innerText = '我是新来的'
        ul.appendChild(li)
      }
    </script>
  </body>

事件捕获

  <style>
      .father {
        width: 300px;
        height: 300px;
        background-color: red;
      }

      .son {
        width: 100px;
        height: 100px;
        background-color: cyan;
      }
    </style>
  </head>
  <body>
    <div class="father">
      <div class="son">111</div>
    </div>

    <script>
      /* 
      1.事件冒泡 : 当触发子元素的事件的时候, 所有的父级元素‘同名事件’都会被依次触发
        元素->父元素->body->html->document->window

      2.事件捕获 : 触发子元素的事件的时候,会从最顶级的父元素一级一级往里触发
        window->document->html->body->d父元素->元素

      3.注册捕获事件 : addEventListener() 第三个参数传true
        * 点语法 和 addEventListener() 默认都是冒泡
      */

      //子元素
      document.querySelector('.son').addEventListener('click',function(){
        alert('我是子元素')
      },true)

      //父元素
      document.querySelector('.father').addEventListener('click',function(){
        alert('我是父元素')
      },true)

      //body
      document.body.addEventListener('click',function(){
        alert('我是body')
      },true)

      //html
      document.documentElement.addEventListener('click',function(){
        alert('我是html')
      },true)

      //document
      document.addEventListener('click',function(){
        alert('我是document')
      },true)

      //window
      window.addEventListener('click',function(){
        alert('我是window')
      },true)
    </script>
  </body>

阻止事件流动

 <style>
      .father {
        width: 300px;
        height: 300px;
        background-color: red;
      }

      .son {
        width: 100px;
        height: 100px;
        background-color: cyan;
      }
    </style>
  </head>
  <body>
    <div class="father">
      <div class="son">111</div>
    </div>

    <script>
      /* 
     阻止事件流动 : 阻止冒泡 + 阻止捕获
        e.stopPropagation()
        
      */

      //子元素
      document.querySelector('.son').addEventListener('click',function(e){
        alert('我是子元素' + e.eventPhase)
        e.stopPropagation()
      },false)

      //父元素
      document.querySelector('.father').addEventListener('click',function(e){
        alert('我是父元素' + e.eventPhase)
      },false)

      //body
      document.body.addEventListener('click',function(e){
        alert('我是body' + e.eventPhase)
      },false)

      //html
      document.documentElement.addEventListener('click',function(e){
        alert('我是html' + e.eventPhase)
      },false)

      //document
      document.addEventListener('click',function(e){
        alert('我是document' + e.eventPhase)
      },true)

      //window
      window.addEventListener('click',function(e){
        alert('我是window' + e.eventPhase)
        e.stopPropagation()
      },true)
    </script>
  </body>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值