Web Apls第五天

87 阅读4分钟

Web Apls第五天

1.事件对象

1.获取事件对象

1.作用:

①是个对象,这个对象里有事件触发时的相关信息

2.获取:

①在事件绑定的回调函数的第一个参数就是事件对象

②一般命名为event、ev、e

3.语法:

元素.addEventlistener('click', function (e))//e事件对象

4.事件对象案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>02-事件对象.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <button>点击点击</button>
    <script>
      // 获取按钮
      const btn = document.querySelector('button');

      btn.addEventListener('click', function (event) {
        console.log(event); // 存放事件触发一瞬间的信息 -  鼠标位置信息
      });
    </script>
  </body>
</html>

2.事件对象常用属性

1.type

①获取当前的事件类型

2.clientX/clientY

①获取光标相对于浏览器可见窗口左上角的位置

3.offsetX/offsetY

①获取光标相对于当前DOM元素左上角的位置

4.key

①用户按下的键盘键的值

②现在不提倡使用keyCode

5.事件对象常用属性案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>03-事件对象-常见属性</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      div{
        width: 300px;
        height: 400px;
        background-color: aqua;
        margin-left: 300px;
      }
    </style>
  </head>
  <body>
    <div>点击点击</div>
    <script>
      // 获取按钮
      const btn = document.querySelector('div');

      btn.addEventListener('mousemove', function (event) {
        // console.log(event.type); // 输出当前的事件类型  少用
        // console.log(event.clientX,event.clientY ); // 返回 鼠标的位置-参照物 页面的左上角即可
        console.log(event.offsetX,event.offsetY);// 返回鼠标的坐标,参照物 是被点击的元素的左上角
      });
    </script>
  </body>
</html>

2.事件流

1.事件流阶段说明

①事件流指的是事件完整执行过程中的流动路径

②假设页面里有个div,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段

③简单来说:捕获阶段是 从父到子 冒泡阶段是从子到父

④如图:

1649847854276

2.事件捕获和事件冒泡

1.事件冒泡概念

① 当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡

②当一个元素触发事件后,会依次向上调用所有父级元素的同名事件

③事件冒泡是默认存在的

2.事件捕获概念

1.概念:

① 从DOM的根元素开始去执行对应的事件 (从外到里)事件捕获需要写对应代码才能看到效果

2.语法:

DOM.addEventListener(事件类型, 事件处理函数, 是否使用捕获机制)

3.说明

①addEventListener第三个参数传入true代表是捕获阶段触发(很少使用)

②若传入false代表冒泡阶段触发,默认就是false

③若是用 L0 事件监听,则只有冒泡阶段,没有捕获

4..事件捕获和冒泡案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>01-事件流动捕获和冒泡.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      div {
        width: 200px;
        height: 200px;
        padding: 20px;
        overflow: hidden;
      }
      .a {
        background-color: red;
      }
      .b {
        background-color: blue;
      }
      .c {
        background-color: green;
      }
    </style>
  </head>
  <body>
    <div class="a"><div class="b"><div class="c"></div>
      </div>
    </div>
    <script>
      const a = document.querySelector('.a');
      a.addEventListener(
        'click',
        function () {
          console.log('a');
        },
        true
      ); // 捕获
      const b = document.querySelector('.b');
      b.addEventListener(
        'click',
        function () {
          console.log('b');
        },
        true
      ); // 捕获
      const c = document.querySelector('.c');
      c.addEventListener(
        'click',
        function () {
          console.log('c');
        },
        false
      );

      /* 
      事件流动 
      1 给多个父子结构的标签绑定事件, 先点击了子元素, 产生事件流动
      2 事件流动 分成了两个阶段
        1 捕获阶段   父节点 流动到 子节点
        2 冒泡节点   子节点 流动到 父节点   默认
        3 例子:
          人 跳水 
          1 水上 水里面 不断下沉 
        4 事件流动方向 默认是 使用了冒泡 - 点击儿子标签 触发 儿子->父亲->爷爷

      3 我们可以修改触发事件 让它选择使用 捕获阶段还是冒泡阶段(默认)
        addEventListener 可以选择使用冒泡还是捕获
        addEventListener(事件类型,事件处理函数,捕获还是冒泡(默认值 false,可以省略))
        addEventListener("click",function(){}, true )

      4 总结
        1 捕获和 冒泡 特点 了解 
        2 默认情况  冒泡 如果想要修改 可以 addEventListener 第三个参数 传入 true即可
        3 以后的代码开发过程中,还是继续使用默认的 冒泡阶段  
       */
    </script>
  </body>
</html>
3.阻止事件流动

1.作用

①默认就有冒泡模式的存在,所以容易导致事件影响到父级元素

②若想把事件就限制在当前元素内,就需要阻止事件流动

③阻止事件流动需要拿到事件对象

④此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效

2.语法:

事件对象.stopPropagetion()

3.鼠标经过事件:

①mouseover 和 mouseout 会有冒泡效果

②ouseenter 和 mouseleave 没有冒泡效果(推荐)

4.阻止默认行为:

①比如链接点击不跳转,表示表单域的没有提交

5.语法:

e.preventDefault()
4.两种注册事件的区别

1.传统on注册(L0)

①同一个对象,后面注册的事件会覆盖前面注册(同一个事件

②直接使用null覆盖偶就可以实现事件的解绑

③都是冒泡阶段执行的

2.事件监听注册(L2)

①语法: addEventListener(事件类型, 事件处理函数, 是否使用捕获)

②后面注册的事件不会覆盖前面注册的事件(同一个事件)

③可以通过第三个参数去确定是在冒泡或者捕获阶段执行

④必须使用removeEventListener(事件类型, 事件处理函数, 获取捕获或者冒泡阶段)

⑤匿名函数无法被解绑

3.事件委托

1.作用

①事件委托是利用事件流的特征解决一些开发需求的知识技巧

2.总结

①优点:给父级元素加事件(可以提高性能)

②原理:事件委托其实是利用事件冒泡的特点, 给父元素添加事件,子元素可以触发

③实现:事件对象.target 可以获得真正触发事件的元素

3.事件委托案例

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>06-事件委托感受.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      ul{
        width: 500px;
        background-color: aqua;
        padding: 50px;
      }
      li{
        background-color: yellow;
        height: 50px;
      }
      a{
        background-color: sandybrown;
      }
    </style>
  </head>
  <body>
    <ul>
      <li><a href="#">1</a></li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
    </ul>
    <script>
      // 点击那个一li标签 颜色设置为红色
      // 以前获取到每一个li标签 数组  遍历他们 按个绑定点击事件
      // const liList=document.querySelectorAll("li");
      // for (let index = 0; index < liList.length; index++) {
      //    liList[index].addEventListener("click",function () {
      //      this.style.backgroundColor="red"
      //    })
      // }

      // 事件委托
      //  本来想要给li标签绑定事件实现业务
      //  把事件绑定写在 父元素上  把li标签应该要做的事情 委托给父元素来做! 
      const ul=document.querySelector("ul");
      ul.addEventListener("click",function (event) {
        //  event.target 有可能是ul标签,有可能是li标签,还有可能是 a标签 
        // 一会再来解决这个问题。
        event.target.style.backgroundColor="red";// 不够完美的
        // event.target 你当前点击的是哪个标签(点击最深最底层的那个标签即可)
        // console.log(event.target);// 获取到被点击的li标签 
      })
    </script>
  </body>
</html>

4.渲染学生信息案例

1.需求

1649849901237

2.实现案例

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>08-综合案例-完成删除功能</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      a {
        text-decoration: none;
        color: #721c24;
      }
      h1 {
        text-align: center;
        color: #333;
        margin: 20px 0;
      }
      table {
        margin: 0 auto;
        width: 800px;
        border-collapse: collapse;
        color: #004085;
      }
      th {
        padding: 10px;
        background: #cfe5ff;

        font-size: 20px;
        font-weight: 400;
      }
      td,
      th {
        border: 1px solid #b8daff;
      }
      td {
        padding: 10px;
        color: #666;
        text-align: center;
        font-size: 16px;
      }
      tbody tr {
        background: #fff;
      }
      tbody tr:hover {
        background: #e1ecf8;
      }
      .info {
        width: 900px;
        margin: 50px auto;
        text-align: center;
      }
      .info input {
        width: 80px;
        height: 25px;
        outline: none;
        border-radius: 5px;
        border: 1px solid #b8daff;
        padding-left: 5px;
      }
      .info button {
        width: 60px;
        height: 25px;
        background-color: #004085;
        outline: none;
        border: 0;
        color: #fff;
        cursor: pointer;
        border-radius: 5px;
      }
      .info .age {
        width: 50px;
      }
    </style>
  </head>

  <body>
    <h1>新增学员</h1>
    <div class="info">
      姓名:<input type="text" class="uname" /> 年龄:<input
        type="text"
        class="age"
      />
      性别:
      <select name="gender" id="" class="gender">
        <option value="男"></option>
        <option value="女"></option>
      </select>
      薪资:<input type="text" class="salary" /> 就业城市:<select
        name="city"
        id=""
        class="city"
      >
        <option value="北京">北京</option>
        <option value="上海">上海</option>
        <option value="广州">广州</option>
        <option value="深圳">深圳</option>
        <option value="曹县">曹县</option>
      </select>
      <button class="add">录入</button>
    </div>

    <h1>就业榜</h1>
    <table>
      <thead>
        <tr>
          <th>学号</th>
          <th>姓名</th>
          <th>年龄</th>
          <th>性别</th>
          <th>薪资</th>
          <th>就业城市</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <!-- <tr>
          <td>1</td>
          <td>这是名称</td>
          <td>这是年龄</td>
          <td>这是性别</td>
          <td>这是工资</td>
          <td>这是所在城市</td>
          <td>
            <a href="javascript:" class="del">删除</a>
          </td>
        </tr> -->
      </tbody>
    </table>
    <script>
      // 1.1 定义数组 负责存放表格要显示的数据
      let arr = [ ];
      const tbody = document.querySelector('tbody');
      // 2  给 录入绑定点击事件
      const add = document.querySelector('.add');
      const uname = document.querySelector('.uname');
      const age = document.querySelector('.age');
      const gender = document.querySelector('.gender');
      const salary = document.querySelector('.salary');
      const city = document.querySelector('.city');

      // 1.2 根据数组渲染页面
      renderTableByArr();

      // 2  按钮绑定点击事件
      add.addEventListener('click', function () {
        // 2.1 创建一个新的对象 把表单数据都合并到对象中
        const data = {
          // 学号
          id: Date.now(),
          // 姓名
          uname: uname.value,
          // 年龄
          age: age.value,
          // 性别
          gender: gender.value,
          // 薪资
          salary: salary.value,
          // 就业城市
          city: city.value,
        };

        // 老师打了一个 断点 来验证 上面的代码 没有写错
        // 2.2 给数组插入新的元素
        arr.push(data);

        // 2.3 数组发生改变  重新调用渲染页面的函数
        renderTableByArr();

        // 2.4 表单数据清空
        uname.value = '';
        age.value = '';
        gender.value = '男';
        salary.value = '';
        city.value = '北京';
      });

      // 3 tbody绑定点击事件,同时判断被点击的是不是 del 删除标签
      tbody.addEventListener('click', function (event) {
        // 3.1 判断当前点击的是不是a标签
        if (event.target.nodeName === 'A') {
          // <a data-index="2" href="javascript:" class="del">删除</a>

          // 获取到a标签 上存放的 index
          // event.target =  a标签的dom元素
          // console.dir(event.target.dataset.index)
          const index = event.target.dataset.index;

          // 3.3 执行数组删除元素
          arr.splice(index,1);

          // 3.4 调用根据数组渲染页面的函数 
          renderTableByArr();
        }
      });
      // 根据数组渲染表格
      function renderTableByArr() {
        let html = ``;
        for (let index = 0; index < arr.length; index++) {
          html += `
         <tr>
          <td>${arr[index].id}</td>
          <td>${arr[index].uname}</td>
          <td>${arr[index].age}</td>
          <td>${arr[index].gender}</td>
          <td>${arr[index].salary}</td>
          <td>${arr[index].city}</td>
          <td>
            <a data-index="${index}" href="javascript:" class="del">删除</a>
          </td>
        </tr>
         `;
        }

        // 把生成的tr插入到 tbody中
        tbody.innerHTML = html;
      }
    </script>
  </body>
</html>

3.示例图

1649850032891