事件冒泡事件委托经典案例.APIs --DOM事件最广泛的应用场景 ----委托事件(内含题目和答案)

        说到DOM,就能想到事件,那事件应用场景是什么呢?

                一定是新增元素的处理了

想要实现新增元素,必须要了解什么是事件委托和事件冒泡

1.事件冒泡 : 当触发子元素的事件的时候, 所有的父级元素‘同名事件’都会被依次触发

        元素->父元素->body->html->document->window

提起事件冒泡,还有一个与之相反的事件,叫做事件捕捉.事件捕捉是以前网景公司的产物,在当时发生了一件离奇的事情,比比尔盖茨为首的微软公司,当时在编程方面有一个最大的对头叫做网景公司,各自占据半壁江山,他们各自对标对方的产品,在微软推出了事件冒泡后,网景随之推出事件捕捉,这种不考虑实际用法的创造就必然会导致公司的下场就不会很好,事件捕捉的用法与事件冒泡截然相反,一个是触发子元素,所有父级元素会依次触发,则事件捕捉则是触发子元素的事件的时候,会从最顶级的父元素一级一级往里触发

元素->父元素->body->html->document->window

网景后来的结果大家可想而知.

      2.事件委托 : 给父元素注册,委托子元素处理

        事件委托原理 :  事件冒泡

        事件委托应用场景 :

          (1)实际开发最多: 给动态新增的子元素注册事件

          (2)性能优化 : 如果所有的子元素都需要注册同名事件,只需要给父元素注册

        事件委托注意点 :

          (1)事件委托不能通过this找到子元素。 (this指向父元素)

          (2)事件委托需要通过什么属性找到子元素:  e.target

直接上图,完成如图案例,DOM知识点就能了解80%

不需要操作样式完成

 表单内上移,下移与删除都需要实现相应的功能

下图为答案

<!DOCTYPE html>
<html>

<head lang="en">
  <meta charset="UTF-8" />
  <title></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>
  <form action="">
    <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>
  </form>

  <h1>人员榜</h1>
  <table>
    <thead>
      <tr>
        <th>学号</th>
        <th>姓名</th>
        <th>年龄</th>
        <th>性别</th>
        <th>薪资</th>
        <th>就业城市</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      <!-- <tr>
          <td>1001</td>
          <td>欧阳霸天</td>
          <td>19</td>
          <td>男</td>
          <td>15000</td>
          <td>上海</td>
          <td>
            <a href="javascript:" class="delete">删除</a>
          </td>
        </tr> -->
    </tbody>

    <script>
      /* 思路分析
          1.点击录入 :(注意点form表单中的按钮需要阻止默认事件)
            1.1 非空判断 : 姓名、年龄、薪资不能为空
            1.2 新增tr元素
              * (1)创建tr  (2)设置内容  (3)添加到table>tbody
            1.3 清空form表单

          2.点击删除 : 使用事件委托技术
            2.1 点击删除, 删除tr标签 ( 删除按钮的父元素的td, td的父元素是tr)

          3.上移

          4.下移
          */


      //1.获取元素
      let uname = document.querySelector('.uname')
      let age = document.querySelector('.age')
      let gender = document.querySelector('.gender')
      let salary = document.querySelector('.salary')
      let city = document.querySelector('.city')
      let add = document.querySelector('.add')
      let i = 100
      //2.1 点击录入
      add.onclick = function (e) {
        /* 注意点:form表单元素中的按钮需要阻止默认条件 */
        e.preventDefault()
        //3.1 非空判断 : 姓名、年龄、薪资不能为空
        if (uname.value.trim() == '' || age.value.trim() == '' || salary.value.trim() == '') {
          alert('输入框不能为空')
        } else {
          //3.2 新增元素
          //(1)创建空tr标签
          let tr = document.createElement('tr')
          //(2)设置内容
          tr.innerHTML = `
              <td>${i++}</td>
              <td>${ uname.value }</td>
              <td>${ age.value }</td>
              <td>${ gender.value }</td>
              <td>${ salary.value }</td>
              <td>${ city.value }</td>
              <td>
                <a href="javascript:" class="up">上移</a>
                <a href="javascript:" class="down">下移</a>
                <a href="javascript:" class="delete">删除</a>
              </td>
              `
          //(3)添加到tbody
          document.querySelector('tbody').appendChild(tr)
        }
        //3.3 表单清空 form.reset()
        document.querySelector('form').reset()
      }


      //2.2 使用事件委托给删除按钮注册点击事件
      /* 
      事件委托 : 给父元素注册事件,委托子元素处理
      事件委托注意点:
        (1)不能使用this : 父元素
        (2)使用e.target : 真正点击的子元素
        (3)委托的父元素也不能是动态新增的
      */
      document.querySelector('tbody').onclick = function (e) {
        //点击tbody任意区域都会触发点击事件, 真正委托的是删除按钮
        /* 
        this : tbody
        e.target : 点击的子元素
         e.target.parentNode.parentNode : tr
        */
        //1.判断点击的是不是删除按钮
        /* 
        (1)  e.target.className == 'delete'
        (2)  e.target.classList.contains('delete')
            true : 有这个类名  false:没有
        */
        let tr = e.target.parentNode.parentNode
        if (e.target.classList.contains('delete')) {
          this.removeChild(tr)
        } else if (e.target.classList.contains('up')) {
          //判断tr是不是第一个儿子
          if (tr.previousElementSibling) { //有哥哥可以上移
            //上移:移到tr哥哥的前面
            this.insertBefore(tr, tr.previousElementSibling)
          } else {
            alert('已经是第一个了')
          }
        } else if (e.target.classList.contains('down')) {
          //判断tr是不是最后一个儿子
          if (tr.nextElementSibling) {
            //下移: 移到 弟弟的弟弟的前面
            this.insertBefore(tr, tr.nextElementSibling.nextElementSibling)
          } else {
            alert('已经是最后一个了')
          }
        }
      }
    </script>
  </table>
</body>

</html>
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值