【JS学习】08. web API-事件进阶

news2024/11/6 16:22:21

Web APIs - 第3天

进一步学习 事件进阶,实现更多交互的网页特效,结合事件流的特征优化事件执行的效率

  • 掌握阻止事件冒泡的方法
  • 理解事件委托的实现原理

事件流

事件流是对事件执行过程的描述,了解事件的执行过程有助于加深对事件的理解,提升开发实践中对事件运用的灵活度。

event

如上图所示,任意事件被触发时总会经历两个阶段:【捕获阶段】和【冒泡阶段】。

简言之,捕获阶段是【从父到子】的传导过程,冒泡阶段是【从子向父】的传导过程。

捕获和冒泡

了解了什么是事件流之后,我们来看事件流是如何影响事件执行的:

<body>
  <h3>事件流</h3>
  <p>事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上。</p>
  <div class="outer">
    <div class="inner">
      <div class="child"></div>
    </div>
  </div>
  <script>
    // 获取嵌套的3个节点
    const outer = document.querySelector('.outer');
    const inner = document.querySelector('.inner');
    const child = document.querySelector('.child');
		
    // html 元素添加事件
    document.documentElement.addEventListener('click', function () {
      console.log('html...')
    })
		
    // body 元素添加事件
    document.body.addEventListener('click', function () {
      console.log('body...')
    })

    // 外层的盒子添加事件
    outer.addEventListener('click', function () {
      console.log('outer...')
    })
    
    // 中间的盒子添加事件
    outer.addEventListener('click', function () {
      console.log('inner...')
    })
    
    // 内层的盒子添加事件
    outer.addEventListener('click', function () {
      console.log('child...')
    })
  </script>
</body>

执行上述代码后发现,当单击事件触发时,其祖先元素的单击事件也【相继触发】,这是为什么呢?

结合事件流的特征,我们知道当某个元素的事件被触发时,事件总是会先经过其祖先才能到达当前元素,然后再由当前元素向祖先传递,事件在流动的过程中遇到相同的事件便会被触发。

再来关注一个细节就是事件相继触发的【执行顺序】,事件的执行顺序是可控制的,即可以在捕获阶段被执行,也可以在冒泡阶段被执行。

如果事件是在冒泡阶段执行的,我们称为冒泡模式,它会先执行子盒子事件再去执行父盒子事件,默认是冒泡模式。

如果事件是在捕获阶段执行的,我们称为捕获模式,它会先执行父盒子事件再去执行子盒子事件。

<body>
  <h3>事件流</h3>
  <p>事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上。</p>
  <div class="outer">
    <div class="inner"></div>
  </div>
  <script>
    // 获取嵌套的3个节点
    const outer = document.querySelector('.outer')
    const inner = document.querySelector('.inner')

    // 外层的盒子
    outer.addEventListener('click', function () {
      console.log('outer...')
    }, true) // true 表示在捕获阶段执行事件
    
    // 中间的盒子
    outer.addEventListener('click', function () {
      console.log('inner...')
    }, true)
  </script>
</body>

结论:

  1. addEventListener 第3个参数决定了事件是在捕获阶段触发还是在冒泡阶段触发
  2. addEventListener 第3个参数为 true 表示捕获阶段触发,false 表示冒泡阶段触发,默认值为 false
  3. 事件流只会在父子元素具有相同事件类型时才会产生影响
  4. 绝大部分场景都采用默认的冒泡模式(其中一个原因是早期 IE 不支持捕获)

阻止冒泡

阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素。

<body>
  <h3>阻止冒泡</h3>
  <p>阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素。</p>
  <div class="outer">
    <div class="inner">
      <div class="child"></div>
    </div>
  </div>
  <script>
    // 获取嵌套的3个节点
    const outer = document.querySelector('.outer')
    const inner = document.querySelector('.inner')
    const child = document.querySelector('.child')

    // 外层的盒子
    outer.addEventListener('click', function () {
      console.log('outer...')
    })

    // 中间的盒子
    inner.addEventListener('click', function (ev) {
      console.log('inner...')

      // 阻止事件冒泡
      ev.stopPropagation()
    })

    // 内层的盒子
    child.addEventListener('click', function (ev) {
      console.log('child...')

      // 借助事件对象,阻止事件向上冒泡
      ev.stopPropagation()
    })
  </script>
</body>

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

鼠标经过事件:

mouseover 和 mouseout 会有冒泡效果

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

事件委托

事件委托是利用事件流的特征解决一些现实开发需求的知识技巧,主要的作用是提升程序效率。

大量的事件监听是比较耗费性能的,如下代码所示

<script>
  // 假设页面中有 10000 个 button 元素
  const buttons = document.querySelectorAll('table button');

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

利用事件流的特征,可以对上述的代码进行优化,事件的的冒泡模式总是会将事件流向其父元素的,如果父元素监听了相同的事件类型,那么父元素的事件就会被触发并执行,正是利用这一特征对上述代码进行优化,如下代码所示:

<script>
  // 假设页面中有 10000 个 button 元素
  let buttons = document.querySelectorAll('table button');
  
  // 假设上述的 10000 个 buttom 元素共同的祖先元素是 table
  let parents = document.querySelector('table');
  parents.addEventListener('click', function () {
    console.log('点击任意子元素都会触发事件...');
  })
</script>

我们的最终目的是保证只有点击 button 子元素才去执行事件的回调函数,如何判断用户点击是哪一个子元素呢?

event

事件对象中的属性 targetsrcElement属性表示真正触发事件的元素,它是一个元素类型的节点。

<script>
  // 假设页面中有 10000 个 button 元素
  const buttons = document.querySelectorAll('table button')
  
  // 假设上述的 10000 个 buttom 元素共同的祖先元素是 table
  const parents = document.querySelector('table')
  parents.addEventListener('click', function (ev) {
    // console.log(ev.target);
    // 只有 button 元素才会真正去执行逻辑
    if(ev.target.tagName === 'BUTTON') {
      // 执行的逻辑
    }
  })
</script>

优化过的代码只对祖先元素添加事件监听,相比对 10000 个元素添加事件监听执行效率要高许多!!!

其他事件

页面加载事件

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

有些时候需要等页面资源全部处理完了做一些事情

事件名:load

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

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

元素滚动事件

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

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

页面尺寸事件

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

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

元素尺寸与位置

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

offsetWidth和offsetHeight

获取出来的是数值,方便计算

注意: 获取的是可视宽高, 如果盒子是隐藏的,获取的结果是0

寸事件

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

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

元素尺寸与位置

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

offsetWidth和offsetHeight

获取出来的是数值,方便计算

注意: 获取的是可视宽高, 如果盒子是隐藏的,获取的结果是0

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

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

相关文章

Hadoop完全分布式环境搭建步骤

【图书介绍】《Spark SQL大数据分析快速上手》-CSDN博客 大数据与数据分析_夏天又到了的博客-CSDN博客 本文介绍Hadoop完全分布式环境搭建方法&#xff0c;这个Hadoop环境用于安装配置Spark。假设读者已经安装好Visual Box 7.0.6虚拟环境与一个CentOS 7虚拟机&#xff08;如果…

H7-TOOL的CAN/CANFD助手增加帧发送成功标识支持, 继续加强完善功能细节

2.27版本固件正式携带此功能&#xff0c;包括之前做的负载率检测和错误信息展示也将集成到这个版本固件中。 对于接收&#xff0c;我们可以直接看到效果&#xff0c;而发送不行&#xff0c;所以打算在发送的地方展示下发送成功标识。CAN发送不像串口&#xff0c;需要等待应答后…

ssm+jsp653基于Javaweb的网上花店系统的设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm 等开发框架&#xff09; vue .net php phython node.js uniapp 微信小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不…

操作系统如何执行,他究竟是个什么

硬件中断 所谓硬件中断&#xff0c;其实也是一个执行信号的过程&#xff0c;具体流程如下。 具体要执行什么方法&#xff0c;只需要拿着对应的信号访问中断向量表就就行比如 N就是像cpu发的中断信号。 时钟中断 但是这里面有一个叫做时钟源的东西&#xff0c;其实也是一个外…

音视频入门基础:FLV专题(24)——FFmpeg源码中,获取FLV文件视频信息的实现

一、引言 通过FFmpeg命令可以获取到FLV文件的视频压缩编码格式、色彩格式&#xff08;像素格式&#xff09;、分辨率、码率、帧率信息&#xff1a; 而由《音视频入门基础&#xff1a;FLV专题&#xff08;9&#xff09;——Script Tag简介》和《音视频入门基础&#xff1a;FLV专…

JMM内存模型(面试回答)

1.什么是JMM JMM就是Java内存模型(java memory model)。因为在不同的硬件生产商和不同的操作系统下&#xff0c;内存的访问有一定的差异&#xff0c;所以会造成相同的代码运行在不同的系统上会出现各种问题。所以Java内存模型(JMM)屏蔽掉各种硬件和操作系统的内存访问差异&…

【stablediffusion又出王炸】IC-Light,可以操控图像生成时的光照,光照难题终于被解决了!

IC-Light代表Impose Constant Light,是一个控制图像照明的项目。可以操控图像生成时的光照&#xff0c;对内容主体重新打光生成符合新背景环境光照的图片。这下商品图合成这种需要最大程度保持原有主体 ID 需求的最大的问题解决了。 Controlnet, Layerdiffusion, IC-light… …

创建线程时传递参数给线程

在C中&#xff0c;可以使用 std::thread 来创建和管理线程&#xff0c;同时可以通过几种方式将参数传递给线程函数。这些方法包括使用值传递、引用传递和指针传递。下面将对这些方法进行详细讲解并给出相应的代码示例。 1. 值传递参数 当你创建线程并希望传递参数时&#xff…

react使用Fullcalendar 实战用法

使用步骤请参考&#xff1a;react使用Fullcalendar 卡片式的日历&#xff1a; 需求图&#xff1a; 卡片式的日历&#xff0c;其实我是推荐 antd的&#xff0c;我两个都写了一下都能实现。 antd 的代码&#xff1a; antd的我直接用的官网示例&#xff1a;antd 日历示例 i…

使用 RabbitMQ 有什么好处?

大家好&#xff0c;我是锋哥。今天分享关于【使用 RabbitMQ 有什么好处&#xff1f;】面试题。希望对大家有帮助&#xff1b; 使用 RabbitMQ 有什么好处&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RabbitMQ 是一种流行的开源消息代理&#xff0c;广…

基于MATLAB的农业病虫害识别研究

matlab有处理语音信号的函数wavread&#xff0c;不过已经过时了&#xff0c;现在处理语音信号的函数名称是audioread选取4.wav进行处理&#xff08;只有4的通道数为1&#xff09; 利用hamming窗设计滤波器 Ham.m function [N,h,H,w] Ham(fp,fs,fc)wp 2*pi*fp/fc;ws 2*pi*…

极简实现酷炫动效:Flutter隐式动画指南第三篇自定义Flutter隐式动画

目录 前言 一、TweenAnimationBuilder 二、使用TweenAnimationBuilder实现的一些动画效果 1.调整透明度的动画 2.稍微复杂点的组合动画 3.数字跳动的动画效果 前言 上两节博客分别介绍了Flutter中的隐式动画的基础知识以及使用隐式动画实现的一些动画效果。当系统提供的隐…

怎么能监控电脑屏幕?四个真心好用的电脑屏幕监控小妙招,一分钟看完!

怎么能监控电脑屏幕&#xff1f;这或许是许多家长、企业管理者和IT安全人员心中的疑问。 有人说&#xff1a;用魔法水晶球&#xff01; 当然&#xff0c;这个方法些许梦幻&#xff0c;现实中我们还是要依靠科技手段来实现电脑屏幕的监控。 接下来&#xff0c;我将为大家介绍四…

中仕公考:25年浙江省公务员考试今日开始报名

2025年浙江省公务员考试于今日开始报名&#xff0c;准备参加考试的各位考生不要错过报名时间! 报名时间&#xff1a;2024年11月6日9时—11月11日17时。 资格初审时间&#xff1a;2024年11月6日9时—11月13日17时。 准考证下载时间&#xff1a;2024年12月3日9时—12月8日17时…

【IEEE出版】第六届国际科技创新学术交流大会暨信息技术与计算机应用学术会议(ITCA 2024,12月06-08)

第六届国际科技创新学术交流大会暨信息技术与计算机应用学术会议&#xff08;ITCA 2024) 2024 6th International Conference on Information Technology and Computer Application 会议官网&#xff1a;itca2024.iaecst.org 会议时间&#xff1a;2024年12月06-08日 截稿时…

SpringMVC总结 我的学习笔记

SpringMVC总结 我的学习笔记 一、SpringMVC简介1.MVC2.SpringMVC概述3. SpringMVC中的核心组件4.SpringMVC核心架构流程 二、SpringMVC框架实例具体实现使用注解实现 四、数据处理及跳转1.结果跳转方式2.处理器方法的参数与返回值处理提交数据数据显示到前端 五、RestFul风格1.…

基于SpringBoot的免税商品优选购物商城的设计与实现

一、项目背景 从古至今&#xff0c;通过书本获取知识信息的方式完全被互联网络信息化&#xff0c;但是免税商品优选购物商城&#xff0c;对于购物商城工作来说&#xff0c;仍然是一项非常重要的工作。尤其是免税商品优选购物商城&#xff0c;传统人工记录模式已不符合当前社会…

【Python】计算机视觉应用:OpenCV库图像处理入门

计算机视觉应用&#xff1a;OpenCV库图像处理入门 在当今的数字化时代&#xff0c;计算机视觉&#xff08;Computer Vision&#xff09;已经渗透到各行各业&#xff0c;比如自动驾驶、智能监控、医疗影像分析等。而 Python 的 OpenCV 库&#xff08;Open Source Computer Visi…

Spring Boot开发入门教程

简介 Spring Boot是一个开源的Java基础框架&#xff0c;用于创建独立、生产级的基于Spring框架的应用程序。通过Spring Boot&#xff0c;你可以轻松地创建独立的、生产级的Spring应用程序。 环境准备 Java开发环境&#xff1a;确保你的机器上安装了Java 8或更高版本。Maven…

vue3入门知识(一)

vue3简介 性能的提升 打包大小减少41%初次渲染快55%&#xff0c;更新渲染快133%内存减少54% 源码的升级 使用Proxy代替defineProperty实现响应式重写虚拟DOM的实现和Tree-Shaking 新的特性 1. Composition API&#xff08;组合API&#xff09; setupref与reactivecomput…