Web前端系列技术之Web APIs基础(从基础开始)④

CSDN话题挑战赛第2期
参赛话题:前端技术分享

Web APIs基础学习四

在前三节的介绍中,主要学习了 对象事件以及相关的 DOM操作 。其中 DOM 操作的主要核心就是 对象操作事件操作 ;在事件操作的语法结构中,基本都是:事件源.事件类型 = 事件处理程序 ,这也是事件的三个要素 :事件源(谁) ,事件类型(要干什么 ,是点击 还是鼠标经过 ,亦或者是键盘弹起时候要干什么),事件处理程序(怎么去干);

对于事件操作,其实在很多项目的开发过程中,都会设计到判断用户操作事件的模块,其主要目的也 为了根据用户所进行的事件操作做出一定决策,以便于给用户带来更好的交互体验

那么该如何实现判断用户所操作的事件呢?

所以,今天主要介绍的内容就是关于DOM的事件高级:
一、事件对象
二、事件流
三、事件委托
四、表格操作案例



一、事件对象

回顾普通事件监听的基础语法结构,可以看到函数中并没有任何参数:

DOM对象.addEventlistener('事件', function (){})

而相对于存在 事件对象 的语法结构而言,可以看到函数中存在了 e 这个参数:

DOM对象.addEventlistener('事件', function (e){})

那么,可以思考的就是:事件对象是什么?如何获取?获取的对象有哪些常用的属性?分两小节展开:

1. 获取事件对象

  1. 事件对象: 也是个对象,这个对象里存在了事件触发时的相关信息,该对象只存在于事件当中;例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息;
  2. 获取方式: 在事件绑定的 回调函数 中,添加的第一个参数,就是事件对象,例如:e

⭐注意:事件对象在开发过程中,一般命名为eventeve,其本质是形参,但并不是用来接受参数的,而是判断事件操作的相关信息的,返回为 PointerEvent

代码样例:

div.addEventListener('click',function(e){
            console.log(e);
})

效果图示(在PointerEvent之下的所有内容都是该事件所具有的操作属性):

在这里插入图片描述

2. 事件对象常用属性

通过上述样例效果图示可看出,事件对象中通常包含很多属性,但是对于前端开发的过程中往往最常用的以下四类:

部分常用属性例举:

  1. type:获取当前的事件类型;
  2. pageX/pageY:获取光标相对于整个HTML页面左上角的位置;
  3. offsetX/offsetY:获取光标相对于当前DOM元素左上角的位置(只有在元素内部点击才有效);
  4. clientX/clientY:获取光标相对于浏览器可见窗口左上角的位置;
  5. key:用户按下的键盘键的值(暂不提倡使用keyCode);

⭐注意:用到按下键盘事件的常用事件是 keydown 或者 keyup ,它们唯一的区别就是触发点不同; keydown 是选择在按下去的一瞬间实现事件触发;而 keyup则是在键盘弹起的一瞬间才会实现事件触发(往往这个兼容性会更好一些);


兼容性应用场景: 为了避免出现在提交输入内容之后,无法实现输入框清空效果,常常选用 keyup 作为键盘按下事件;


二、事件流

一个项目中,某个事件在完整的执行过程中所流经的路径就是 事件流 ,事件流当中通常又会分为两个阶段:事件捕获事件冒泡,不同的阶段可以处理不同的事务,但是对于不同的 父子级事件 处理而言,事件之间也会存在相互的影响,解决这种影响就需要运用到 阻止事件流动 的操作了,下面均会详细介绍:

1. 阶段说明

假设页面中含有一个div,当触发事件时,便会经历两个阶段,分别是 捕获阶段冒泡阶段 ,如图所示:

在这里插入图片描述

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

2. 事件捕获

基础概念:DOM的根元素开始去执行对应的事件( 从外到里 ),需要写对应代码才能看到效果;

基本语法结构:

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

说明:
addEventListener 第三个参数传入 true 代表的是捕获阶段触发(很少使用);
② 若传入 false 代表冒泡阶段触发,默认就是 false
③ 若是用 L0 事件监听,则只有冒泡阶段,没有捕获;

3. 事件冒泡

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

简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件;

说明:
① 事件冒泡是默认存在的;
② 同名的事件才会出现冒泡的情况;

4. 阻止事件流动

为什么要阻止事件流动?

原因:默认就有冒泡模式的存在,所以很容易导致事件影响到父级元素,但是若想把事件就限制在当前元素内,那么就需要 阻止事件流动

方式一:

事件对象.stopPropagation()

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

方式二:

鼠标经过事件:

  1. mouseovermouseout 会有冒泡效果
  2. mouseentermouseleave 没有冒泡效果(推荐)

说明:
① 此方法只能用于鼠标经过事件;

方式三:

事件对象.preventDefault()

说明:
① 阻止默认行为,比如链接点击不跳转,表单域的跳转

5. 两种注册事件下阻止事件流动的区别

传统 on 注册(L0)

  1. 同一个对象,后面注册的事件会覆盖前面注册(同一个事件) ;
  2. 直接使用 null 覆盖,就可以实现事件的解绑;
  3. 都是冒泡阶段执行的;

事件监听注册(L2)

  1. 语法: addEventListener(事件类型, 事件处理函数, 是否使用捕获)
  2. 后面注册的事件不会覆盖前面注册的事件(同一个事件);
  3. 可以通过第三个参数去确定是在冒泡或者捕获阶段执行;
  4. 必须使用 removeEventListener(事件类型, 事件处理函数, 获取捕获或者冒泡阶段)
  5. 匿名函数无法被解绑

三、事件委托

基础概念:其也可称之为 事件代理(Event Delegation);是JavaScript中常用绑定事件的常用技巧。顾名思义,事件代理 就是把原本需要绑定在子元素的响应事件委托给父元素,让父元素担当事件监听的职务。事件代理 的原理是DOM元素的事件冒泡;

说明:
① 优点:给父级元素加事件(可以提高性能);
② 原理:事件委托其实是利用事件冒泡的特点;
③ 实现:事件对象.target 可以获得真正触发事件的元素;

⭐注意:

  1. 单个事件没有必要用事件委托;
  2. 多个事件也需要分析才能知道是否应该使用事件委托,具体什么时候能需要使用事件委托;
  3. 部分情况可直接替代了for循环的遍历需求;

四、表格操作案例

具体代码:

    //  1. 准备好数据后端的数据
    let arr = [
      { stuId: 1001, uname: '小柴爱程序', age: 23, gender: '男', salary: '20000', city: '杭州' },
    ]
    // 获取父元素 tbody
    let tbody = document.querySelector('tbody')
    // 添加数据按钮 
    // 获取录入按钮
    let add = document.querySelector('.add')
    // 获取各个表单的元素
    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')
    // 渲染函数  把数组里面的数据渲染到页面中
    function render() {
      // 先干掉以前的数据  让tbody 里面原来的tr 都没有
      tbody.innerHTML = ''
      // 在渲染新的数据
      // 根据数据的条数来渲染增加 tr  
      for (let i = 0; i < arr.length; i++) {
        // 1.创建tr  
        let tr = document.createElement('tr')
        // 2.tr 里面放内容
        tr.innerHTML = `
        <td>${arr[i].stuId}</td>
        <td>${arr[i].uname}</td>
        <td>${arr[i].age}</td>
        <td>${arr[i].gender}</td>
        <td>${arr[i].salary}</td>
        <td>${arr[i].city}</td>
        <td>
          <a href="javascript:" id="${i}">删除</a>
        </td>
        `
        // 3.把tr追加给 tobdy  父元素.appendChild(子元素)
        tbody.appendChild(tr)
      }
    }
    // 页面加载就调用函数
    render()
    add.addEventListener('click', function () {
      // alert(11)
      // 获得表单里面的值   之后追加给 数组 arr  用 push方法
      arr.push({
        // 得到数组最后一条数据的学号 1003    + 1
        stuId: arr[arr.length - 1].stuId + 1,
        uname: uname.value,
        age: age.value,
        gender: gender.value,
        salary: salary.value,
        city: city.value
      })
      // console.log(arr)
      // 重新渲染函数
      render()
      // 复原所有的表单数据
      uname.value = age.value = salary.value = ''
      gender.value = '男'
      city.value = '北京'
    })
    // 删除操作, 删除的也是数组里面的数据 , 用事件委托
    tbody.addEventListener('click', function (e) {
      if (e.target.tagName === 'A') {
        arr.splice(e.target.id, 1)
        // 重新渲染函数
        render()
      }
    })

具体效果图如下:

在这里插入图片描述


总结

今天是继续学习Web APIs的第四天,内容不多,但练习极为重要,今天所总结出来的所有知识,希望对大家有用,同时也希望这篇文章可以有一个好的展现量和得到更多人的支持,谢谢每一位浏览文章的人,要相信小柴码文,必是好文,欢迎各位 点赞+收藏+关注 啦! ! !


以上就是所要介绍的Web APIs基础学习的第四节内容,后续即将更新前端开发的学习目标。感谢关注和支持,让我们一起成长!

有兴趣可回顾一下JavaScript基础学习的文章内容,再结合之前所介绍的CSS基础学习以及HTML基础学习,大脑里的内容会更加丰富而充实的,毕竟综合性复习和学习是更会加深印象的哟!!!

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力学前端的小柴

感谢有你,汪~汪~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值