7-WebApis-3

news2024/9/23 23:23:26

Web APIs - 3

目标:学习事件流,事件委托,其他事件等知识,优化多个事件绑定和实现常见网页交互

  • 事件流
  • 移除事件监听
  • 其他事件
  • 元素尺寸与位置
  • 综合案例

在这里插入图片描述

事件流

为什么要学习事件流?

  • 可以帮我们解决一些疑惑,比如点击子盒子会会弹出2次的问题

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

当触发事件时,会经历两个阶段,分别是捕获阶段冒泡阶段

在这里插入图片描述

事件捕获概念:

当一个元素的事件被触发时,会从DOM的根元素开始依次调用同名事件 (从外到里)

捕获

事件捕获需要写对应代码才能看到效果

语法:

 元素.addEventListener('click', 回调函数, 是否使用捕获)  
<body>
  <div class="father">
    父盒子
    <div class="son">子盒子</div>
  </div>
  <script>
    // 事件流
    const father = document.querySelector('.father')
    const son = document.querySelector('.son')
    // 1. 事件捕获
    // // 点击父盒子
     father.addEventListener('click', function () {
       alert('我是爸爸')
     }, true)  // 事件捕获
     // 点击子盒子
     son.addEventListener('click', function () {
       alert('我是儿子')
     }, true) // 事件捕获
  </script>
</body>

说明:

  • addEventListener第三个参数传入 true 代表是捕获阶段触发(很少使用)
  • 若传入false代表冒泡阶段触发,默认就是 false

事件冒泡

事件冒泡概念:

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

  • 简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的 同名事件
  • 事件冒泡是默认存在的,或者第三个参数传入 false 都是冒泡
  • 实际工作都是使用事件冒泡为主
<body>
  <div class="father">
    父盒子
    <div class="son">子盒子</div>
  </div>
  <script>
    // 事件流
    const father = document.querySelector('.father')
    const son = document.querySelector('.son')
    // 2. 事件冒泡
    // 点击父盒子
    father.addEventListener('click', function () {
      alert('我是爸爸')
    })
    // 点击子盒子
    son.addEventListener('click', function () {
      alert('我是儿子')
    }, false) 
  </script>
</body>

阻止冒泡

问题:因为默认就有冒泡阶段的存在,所以容易导致事件影响到父级元素(祖先元素)

需求:若想把事件就限制在当前元素内,就需要阻止事件冒泡

前提:

阻止事件冒泡需要拿到事件对象

<body>
  <div class="father">
    父盒子
    <div class="son">子盒子</div>
  </div>
  <script>
    // 事件流
    const father = document.querySelector('.father')
    const son = document.querySelector('.son')
    // 1. 事件冒泡
    // 点击父盒子
    father.addEventListener('click', function () {
      alert('我是爸爸')
    })
    // 点击子盒子
    son.addEventListener('click', function (e) {
      alert('我是儿子')
      // 1.1 先获取事件对象
      // 1.2 事件对象.stopPropagation()  注意是个方法 
      e.stopPropagation()
    }) 
  </script>
</body>

结论:事件对象中的 ev.stopPropagation 方法,专门用来阻止事件冒泡(事件传播)

鼠标经过事件:

mouseover 和 mouseout 会有冒泡效果

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

事件委托

事件委托(EventDelegation):是JavaScript中注册事件的常用技巧,也称为事件委派、事件代理

简单理解:原本需要注册在子元素的事件委托给父元素,让父元素担当事件监听的职务

为什么要用事件委托呢?

  • 如果同时给多个元素注册事件,还需要利用循环多次注册事件
  • 大量的事件监听是比较耗费性能的,如下代码所示
<script>
  // 假设页面中有 10000 个 button 元素
  const buttons = document.querySelectorAll('table button');

  for(let i = 0; i <= buttons.length; i++) {
    // 为 10000 个 button 元素添加了事件
    buttons.addEventListener('click', function () {
      // 省略具体执行逻辑...
    })
  }
</script>

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

  • 优点:减少注册次数,可以提高程序性能
  • 原理:事件委托其实是利用事件冒泡的特点
    • 给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件

利用事件委托方式如何得到当前点击的元素呢?

  • 实现:事件对象.target. tagName 可以获得真正触发事件的元素
<body>
  <ul>
    <li>第1个孩子</li>
    <li>第2个孩子</li>
    <li>第3个孩子</li>
    <li>第4个孩子</li>
    <li>第5个孩子</li>
  </ul>
  <script>
    // 需求: 点击每个小li都会有弹窗效果
    // 1. 获取父元素ul
    const ul = document.querySelector('ul')

    // 2. 给ul注册点击事件
    ul.addEventListener('click', function (e) {
      // alert('我会弹窗')
      // 3. 利用事件对象.target 得到目标元素
      // console.log(e.target)
      // e.target.style.color = 'pink'

      // 需求2:点击哪个小li,对应的li变色
      // console.dir(e.target.tagName) 可以得到目标元素的标签名
      if (e.target.tagName === 'LI') {
        e.target.style.color = 'pink'
      }
    })
  </script>

阻止默认行为

阻止元素发生默认的行为

例如:

  • 当点击提交按钮时阻止对表单的提交
  • 阻止链接的跳转等等

语法:

事件对象.preventDefault()
<body>
  <form action="">
    姓名: <input type="text" name="username">
    <button>提交</button>
  </form>
  <a href="http://www.baidu.com">点击跳转</a>
  <script>
    // 阻止默认行为
    const form = document.querySelector('form')
    const input = document.querySelector('[name=username]')
    form.addEventListener('submit', function (e) {
      // 如果input表单的值为空则不允许提交
      if (input.value === '') {
        // return 无法阻止提交事件
        e.preventDefault()  // 阻止提交事件
      }
    })

    document.querySelector('a').addEventListener('click', function (e) {
      e.preventDefault()
    })
  </script>
</body>

事件解绑(了解)

移除事件处理函数,也称为解绑事件

<body>
  <button class="l2">移除L2事件监听</button>
  <button class="l0">移除L0事件监听</button>
  <script>
    // 需求:按钮就点击一次,然后移除点击事件

    // 1. l2事件监听
    const l2 = document.querySelector('.l2')

    l2.addEventListener('click', fn)
    function fn() {
      alert('我点击了')
      // 移除事件监听
      l2.removeEventListener('click', fn)
    }

    // 2. l0事件监听
    const l0 = document.querySelector('.l0')
    l0.onclick = function () {
      alert('我点击了')
      // 移除事件监听
      l0.onclick = null
    }
  </script>
</body>

其他事件

页面加载事件

加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件

为什么要学?

  • 有些时候需要等页面资源全部处理完了做一些事情
  • 老代码喜欢把 script 写在 head 中,这时候直接找 dom 元素找不到

事件名:load

监听页面所有资源加载完毕:

window.addEventListener('load', function() {
    // xxxxx
})

当初始的 HTML 文档被完全加载和解析完成之后就触发,而无需等待样式表、图像等完全加载

事件名:DOMContentLoaded

document.addEventListener('DOMContentLoaded', function() {
    // xxxxx
})

元素滚动事件

滚动条在滚动的时候持续触发的事件

为什么要学?

  • 很多网页需要检测用户把页面滚动到某个区域后做一些处理,比如固定导航栏,比如返回顶部

事件名:scroll

监听整个页面滚动:

window.addEventListener('scroll', function() {
    // xxxxx
})

scrollTop / scrollLeft, 被卷去的头部或者左侧,可以读取,也可以修改(赋值)

页面尺寸事件

会在窗口尺寸改变的时候触发事件:

window.addEventListener('resize', function() {
    // xxxxx
})

clientWidth和clientHeight,获取元素的可见部分宽高(不包含border,margin,滚动条等)

元素尺寸与位置

获取元素的自身宽高、包含元素自身设置的宽高、padding、border

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/689724.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

npm全局安装的包在cmd能找到,在powershell中找不到

背景 使用npm i g 全局安装的包&#xff0c;比如&#xff1a;eslint&#xff1b;安装完成后&#xff0c;执行eslint相关命令&#xff0c;显示命令不存在&#xff1b;以为是node没配置全局环境变量&#xff0c;检查发现配置了&#xff1b;后来试了一下在cmd是可以使用的&#x…

蓝桥杯专题-试题版-【十进制转十六进制】【十六进制转八进制】【十六进制转十进制】【数的读法】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

TCP客户端的WPF实现

1、TCP实现类 internal class TcpClient{Socket ClientSocket { get; set; }public byte[] ReceiveBuffer { get; set; }/// <summary>/// 构造函数/// </summary>/// <param name"receiveBufferLength"></param>public TcpClient(int rece…

关于Eclipse 运行JavaWeb项目发生Source not found的情况

描述是说&#xff0c;class源文件未找到。其实问题就是出在没有部署。但是我们查看部署时&#xff0c;发现我们已经部署过了。 其实&#xff0c;这个比较细节的地方。 你可以右键单击这个jsp项目&#xff0c;然后点击 run as。发现它其实是没有配置run运行文件。这就导致是发现…

【wireshark】时间显示

默认的好像是个相对时间 可以显示当前时间 在视图里选择

Xcode 常用操作相关

代码折叠 选择 Xcode -> Preferences -> Text Editing勾选Code folding ribbon 清空最近打开项目 File -> Open Recent -> Clear Menu

模板匹配Template Matching

实现代码&#xff1a; import cv2 import numpy as np def template_demo(tpl,target):methods[cv2.TM_SQDIFF_NORMED,cv2.TM_CCORR_NORMED,cv2.TM_CCOEFF_NORMED]th,twtpl.shape[:2]for md in methods:start_timecv2.getTickCount()# 匹配结果resultcv2.matchTemplate(target…

【Linux】linux | shell | 获取日期

1、获取上一天 1&#xff09;代码 date -d "1 days ago" %Y-%m-%d 2&#xff09;结果 ~~

chatgpt赋能python:Python计算累乘的优秀解决方案

Python计算累乘的优秀解决方案 在python编程中&#xff0c;经常需要进行数值计算。其中一个最基本的计算就是累乘。累乘可以基于一组数字进行&#xff0c;计算它们的乘积。比如&#xff0c;如果输入的数字序列是[1,2,3,4]&#xff0c;则累乘结果为24。 在本文中&#xff0c;我…

MediaPipe简介

有没有想过“OK Google”背后的含义是什么?嗯,这就是 MediaPipe。如果您刚刚开始使用 MediaPipe,并且这是您阅读的第一篇文章,那么恭喜您,您找到了正确的地方。本文将介绍MediaPipe的基础知识、解决方案之间的差异以及框架。 官方文档指出,推理是实时的,只需几行代码即可…

Qt定时器类QTimer

目录 public/slot function signals static public function 示例&#xff08;获取系统时间并且将其显示到窗口中&#xff09;&#xff1a; 示例主要代码&#xff08;每间隔一秒向控制台发送一条消息&#xff09;&#xff1a; 注意事项&#xff1a; Qt定时器类QTimer是一个…

Bootstrap CSS 概览

文章目录 Bootstrap CSS 概览HTML 5 文档类型&#xff08;Doctype&#xff09;移动设备优先响应式图像全局显示、排版和链接基本的全局显示排版链接样式 避免跨浏览器的不一致容器&#xff08;Container&#xff09;Bootstrap 浏览器/设备支持 Bootstrap CSS 概览 在这一章中&a…

iOS-苹果内购的流程图

关于苹果内购的开发文章有很多&#xff0c;如&#xff1a; Flutter上线项目实战——苹果内购 苹果内购流程&#xff0c;看我就足够了 - 简书 。 下面这是一张苹果内购的流程图。 ​​​​​​​ 该图来源于苹果官网&#xff0c;但不够清晰&#xff0c;欢迎各位网络大牛 告知…

关于cdh环境中zookeeper启动失败NodeManager内存溢出无法链接等的问题

在此记录一下 1、zookeeper一直启动失败&#xff1a; 看你的事物目录配置的是什么 解决方法&#xff1a;删除掉/var/lib/zookeeper/version-2 为0kb的有问题文件&#xff0c;问题解决 2、NodeManager内存溢出无法链接等的问题 注意几点&#xff1a; 1、这里不能超过物理内存…

MySQL数据库学习(保姆级教程)(1.7W字)

1.初识MySQL JavaEE:企业级Java开发 Web 前端&#xff08;页面&#xff1a;展示&#xff0c;数据&#xff01;&#xff09; 后台&#xff08;连接点&#xff1a;连接数据库JDBC&#xff0c;链接前端&#xff08;控制&#xff0c;控制视图跳转&#xff0c;和给前端传递数据&a…

h.264与h.265有什么区别

H.265是新的编码协议&#xff0c;是H.264的升级版。H.265相比H.264最主要的改变是采用了块的四叉树划分结构&#xff0c;也极大了优化了算法&#xff0c;H.265比H.264占用的存储空间理论上要少50%。H.265在各方面都碾压了H.264。 1&#xff0c;H265优点&#xff1a;降低存储空间…

行列转换(一)• MySQL版

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习&#xff0c;有基础也有进阶&#xff0c;有MySQL也有Oracle 行列转换 • Mysql版 1.准备操作2.行转列1.1为何进…

vue前端和nodejs后端使用socket.io无法通信问题解决

(128条消息) 使用 socket.io 跨域问题的解决&#xff08;整理了四种方法&#xff0c;总有成功的&#xff01;&#xff09; Access to XMLHttpRequest at ‘http://localhost:4000/socket.io_socket io()出现跨域问题_it1790的博客-CSDN博客 socket.io的版本是4.6.2

【Java】Java核心 73:XML (中)

文章目录 5 XML的组成&#xff1a;字符区(了解)**6** **DTD约束(能够看懂即可)****1** **什么是DTD****2** **DTD约束的实现和语法规则&#xff08;看懂dtd约束&#xff0c;书写符合规范的xml文件&#xff09;** 5 XML的组成&#xff1a;字符区(了解) 当大量的转义字符出现在x…

MATLAB随机打乱矩阵(按行或列)

1、重新排列矩阵各行 a [1 2;3 4;5 6;7 8]; rowrank randperm(size(a, 1)); % size获得a的行数&#xff0c;randperm打乱各行的顺序 a1 a(rowrank,:) % 按照rowrank重新排列各行&#xff0c;注意rowrank的位置2、重新排列矩阵各列 b [1 3 5 7;2 4 6 8 ]; r…