JS30 Day 25:Event Capture, Propagation, Bubbling and Once学习笔记

今天这章节主要是在练习事件绑定相关的知识。

https://ithelp.ithome.com.tw/upload/images/20201123/201261824mAN2Kt9ta.png

主要以上面的画面来做事件的操作。

  <button>BTN</button>
  <div class="one">
    <div class="two">
      <div class="three">
      </div>
    </div>

    <ul>
      <li><a href="javascript:;">Button1</a></li>
      <li><a href="javascript:;">Button2</a></li>
      <li><a href="javascript:;">Button3</a></li>
    </ul>
  </div>

addEventListener

有分为三个参数。
1.事件类型(event)。
2.回呼函数(callback)。
3.设定(options) (替换掉原本的捕获(capture))。

事件分为两种模式。
1.捕获(capture):由外至内。
2.冒泡(bubbling)):由内至外。

此为最基本事件绑定的操作。

      let btn = document.querySelector("button");
      btn.addEventListener("click", btnHandler, {
        // options常用的参数,并以物件型式呈现,预设都为false
        // capture(boolean):true为捕获模式,反之冒泡 , once(boolean):只执行一次
        capture: true,
        once: true
      });

      function btnHandler() {
        console.log("click");
      }

利用one,two,three(外至内)的区域来做操作。

使用预设的options,事件模式为冒泡。

 let divs = document.querySelectorAll('div');
      divs.forEach(div => {
        div.addEventListener('click', divHandler, {
          capture: false,
          once: false
        })
      })

当我们阻止事件进行传递。
为捕捉模式时,只会获取最外层(one),因为无法进行事件传递。
为冒泡模式时,只会获取当前层(one,two,three),因为无法进行事件传递。

      function divHandler(e) {
        e.stopPropagation(); // 可阻止当前事件继续进行捕捉(capturing)及冒泡(bubbling)传递。
        console.log(this.className); // capture: false => three two one / true => one
        console.log(e.path, e.composedPath()); // [div.three, div.two, div.one, body.bod, html, document, Window] , [//]
      }

绑定事件:各别将事件绑到指定的dom上,而如果动态增加dom元素的话,新增的dom就不会被绑到事件。

      let as = document.querySelectorAll('a');
      as.forEach(a => {
        a.addEventListener('click', aHandler, {
          capture: false,
          once: false
        })
      })

target就是我们最深层的目标currentTarget就是绑定事件的目标
点击Button1,2,3後,会显示对应的讯息,委派的讯息(ul部分)也会显示出来,但当我们动态新增li之後再点击,发现绑定事件的讯息已经不见了

      function aHandler(e) {
        console.log("Bind : a click", "target", e.target, "currentTarget", e.currentTarget);
        // target <a href="javascript:;">Button3</a> , currentTarget <a href="javascript:;">Button3</a>
      }

委派事件:也就是将事件监听做在外层,控制其委派范围内的dom,动态新增进来的dom也能获取事件。

https://ithelp.ithome.com.tw/upload/images/20201123/20126182teU4fEJXdj.png

      let ul = document.querySelector('ul');
      ul.addEventListener('click', ulHandler)

当Button1,2,3後,会显示对应的讯息,当我们动态新增li之後再点击,发现委派事件的讯息依然会显示
而我们在委派时,可以利用判断if去筛选我们所需的dom。

      function ulHandler(e) {
        // 加以判断是否为a标签(nodeName会将标签转为大写)
        if (e.target.nodeName === "A") {
          console.log("delegate : a click", "target", e.target, "currentTarget", e.currentTarget);
          // target <a href="javascript:;">Button3</a>  , currentTarget <ul>…</ul> 
        }
      }

<<:  MySQL 数字类型资料之基本操作

>>:  用排队上厕所来比喻Python Thread的Lock机制!

[Day 29] 完成注册功能

在昨天取得了注册资讯 今天来把他写入DB里面 把前面几天的後台系统的MongoDB部分拿出来做使用 ...

误用案例测试(Misuse case testing)最不可能包含在软件整合测试(integration test)中

-代码仓库:git 顾名思义,整合测试结合了代码单元、模组或子系统并对其进行测试。在托管代码储存库...

D9: 工程师太师了: 第5话

工程师太师了: 第5话 杂记: 我很建议大家在下班之余, 如果有些闲暇可以做side project...

[Day25] swift & kotlin 游戏篇!(7) 小鸡BB-游戏制作-API与游戏动画

游戏示意 swift - 游戏功能 接下来当我们点击按钮 我们来打个API 并告知道有没有猜对 来看...

JavaScript学习日记 : Day7 - 函数(二)

ES6出现的Arrow function,看起来简短许多,但却充满许多陷阱(限制),所以充份了解箭头...