浅谈js事件机制

news2024/11/29 2:48:04
  • 事件是什么?
  • 事件模型?
    • 原始事件模型(DOM0级)
      • HTML代码中指定属性值:
      • 在js代码中指定属性值:
      • 优点:
      • 缺点:
    • IE 事件模型
    • DOM2事件模型
  • 对事件循环的理解
    • 宏任务(Macrotasks)
    • 微任务(Microtasks)
    • Event Loop 执行顺序如下所示:

事件是什么?

事件是 用户操作网页时发生的交互动作,比如 click/move, 事件除了用户触发的动作外,还可以是文档加载,窗口滚动和大小调整。

事件被 封装成一个 event 对象,包含了该事件发生时的所有相关信息( event 的属性)以及可以对事件进行的操作( event 的方法)。

事件模型?

JavaScript事件模型指的是一种基于事件驱动的编程模式,用于处理浏览器和用户发生的事件。当用户或浏览器执行某个动作时,例如点击某个元素或者提交表单,JavaScript就会将这些动作封装为一个事件,并将该事件传递给注册了该事件的回调函数。

JavaScript中的事件分为两种类型:

  • 原生事件
  • 自定义事件。

原生事件是由浏览器定义的事件,如点击、滚动、鼠标移动等,而自定义事件是由开发人员自己定义的事件。

在JavaScript事件模型中,当一个事件发生时,浏览器会将该事件封装成一个事件对象,并将其传递给注册了该事件的回调函数。

开发人员可以通过addEventListener()方法来向一个元素注册一个事件监听器,该方法接受三个参数:事件类型、回调函数和一个布尔值,指示回调函数是在事件捕获阶段还是事件冒泡阶段被调用。

事件捕获是从顶层元素开始,向下级元素逐层传递事件的过程,直到抵达目标元素。事件冒泡则是从目标元素开始,向上级元素逐层传递事件的过程,直到抵达顶层元素。开发人员可以根据需要选择事件捕获还是事件冒泡阶段来注册事件监听器。

在事件处理函数中,开发人员可以使用event对象来访问事件相关的信息,如事件类型、目标元素、鼠标位置等。同时,还可以通过event.preventDefault()方法来阻止默认行为,或通过event.stopPropagation()方法来阻止事件传播。

在JavaScript中,事件模型是一种非常重要的编程模式,可以帮助开发人员更好地处理用户交互、浏览器行为等方面的问题。

事件是用户操作网页时发生的交互动作或者网页本身的一些操作,现代浏览器一共有三种事件模型:

原始事件模型(DOM0级)

在原始事件模型中,事件发生后没有传播的概念,所以没有事件流的概念。

但是现在有的浏览器支持以冒泡的方式实现,它可以在网页中直接定义监听函数,也可以通过 js 属性来指定监听函数。

事件发生,马上处理。监听函数只是元素的一个属性值,通过指定元素的属性值来绑定监听器。

直接在 dom 对象上注册事件名称,就是 DOM0 写法

书写方式有两种:

HTML代码中指定属性值:
<input type="button" onclick="func1()" />
在js代码中指定属性值:
document.getElementsByTagName(‘input’)[0].onclick = func1
优点:

所有浏览器都兼容

缺点:
  • 逻辑与显示没有分离;
  • 相同事件的监听函数只能绑定一个,后绑定的会覆盖掉前面的,如:a.onclick = func1; a.onclick = func2;将只会执行func2中的内容;
  • 无法通过事件的冒泡、委托等机制完成更多事情;

IE 事件模型

“IE不把该对象传入事件处理函数,由于在任意时刻只会存在一个事件,所以IE把它作为全局对象window的一个属性”,用IE8执行了代码alert(window.event),结果弹出是null,说明该属性已经定义,只是值为null(与undefined不同),

代码如下:

window.onload = function (){alert(window.event);}

setTimeout(function(){alert(window.event);}2000);

第一次弹出【object event】,两秒后弹出依然是null。

由此可见IE是将event对象在处理函数中设为window的属性,一旦函数执行结束,便被置为null了;

在该事件模型中,一次事件共有两个过程:

  • 事件处理阶段(先执行元素的监听函数,)
  • 事件冒泡阶段(然后事件沿着父节点一直冒泡到document。)

事件处理阶段会首先执行目标元素绑定的监听事件。

然后是事件冒泡阶段,冒泡指的是事件从目标元素冒泡到document,依次检查经过的节点是否绑定了事件监听函数,如果有则
执行。

这种模型通过 attachEvent 来添加监听函数,可以添加多个监听函数,会按顺序依次执行。

IE模型下的事件监听方式比较独特,绑定监听函数的方法是:

attachEvent( "eventType""handler");//其中evetType为事件的类型,

如onclick,注意要加’on’。解除事件监听器的方法是:

detachEvent("eventType""handler" )

IE的事件模型已经可以解决原始模型的三个缺点,但其自己的缺点就是兼容性,只有IE系列浏览器才可以这样写。

更多详细内容,请微信搜索“前端爱好者戳我 查看

DOM2事件模型

此模型是W3C制定的标准模型,既然是标准,现代浏览器(指IE6~8除外的浏览器)都已经遵循这个规范。

W3C制定的事件模型中,一次事件的发生包含三个过程:

  • capturing phase:事件捕获阶段。事件被从document一直向下传播到目标元素,在这过程中依次检查经过的节点是否注册了该事件的监听函数,若有则执行;
  • target phase:事件处理阶段。事件到达目标元素,执行目标元素的事件处理函数;
  • bubbling phase:事件冒泡阶段。事件从目标元素上升一直到达document,同样依次检查经过的节点是否注册了该事件的监听函数,有则执行;

这种事件模型,事件绑定的函数是 addEventListener,其中第三个参数可以指定事件是否在捕获阶段执行。

所有的事件类型都会经历captruing phase但是只有部分事件会经历bubbling phase阶段,例如submit事件就不会被冒泡。

标准的事件监听器绑定:

addEventListener("eventType""handler""true|false");

其中eventType指事件类型。第二个参数是处理函数,第三个即用来指定是否在捕获阶段进行处理,一般设为false来与IE保持一致。

监听器的解除也类似:

removeEventListner("eventType""handler""true!false");

以上便是事件的三种模型,我们在开发的时候需要兼顾IE与非IE浏览器,所以注册一个监听器应该这样写:

var a = document.getElementById('a');
if(a.attachEvent){
    a.attachEvent('onclick',func);
}
else{
    a.addEventListener('click',func,false);
}

对事件循环的理解

因为 js 是单线程运行的,在代码执行时,通过将不同函数的执行上下文压入执行栈中来保证代码的有序执行。

在执行同步代码时,如果遇到异步事件,js 引擎并不会一直等待其返回结果,而是会将这个事件挂起,继续执行执行栈中的其他任务。

当异步事件执行完毕后,再将异步事件对应的回调加入到一个任务队列中等待执行。

任务队列可以分为:

  • 宏任务队列
  • 微任务队列

宏任务(Macrotasks)

宏任务(Macrotasks)包括以下几种常见的操作:

  1. setTimeout和setInterval: 通过定时器设置的回调函数会被添加到宏任务队列中,等待执行。

  2. I/O 操作:涉及到网络请求、文件读写等的异步操作会被添加到宏任务队列中。

  3. UI 渲染:渲染引擎会将UI渲染任务添加到宏任务队列中。

  4. 事件处理程序:例如点击事件、键盘事件等会触发相应的回调函数,这些回调函数也会被添加到宏任务队列中。

微任务(Microtasks)

微任务(Microtasks)则是具有更高优先级的异步操作,它们会在当前宏任务执行完毕后立即执行。

常见的微任务包括:

  1. Promise回调函数: 当Promise对象状态变为resolved或rejected时,相关的回调函数会被添加到微任务队列中。

  2. MutationObserver: 监听DOM树变化的回调函数会被添加到微任务队列中。

  3. process.nextTick(Node.js环境): 在Node.js环境中,process.nextTick函数添加的回调函数会被添加到微任务队列中。

对于执行顺序,当一个宏任务执行完毕后,会先执行所有的微任务队列中的任务,直到微任务队列为空,然后再执行下一个宏任务。这样的循环保证了微任务具有更高的优先级,能够及时处理一些重要的回调函数。

总结,

  • 宏任务包括定时器、I/O操作、UI渲染和事件处理程序等,
  • 而微任务包括Promise回调函数和MutationObserver等。

微任务比宏任务具有更高的优先级,在当前宏任务结束后立即执行。

当当前执行栈中的事件执行完毕后,js 引擎首先会判断微任务队列中是否有任务可以执行,如果有就将微任务队首的事件压入栈中执行。当微任务队列中的任务都执行完成后再去执行宏任务队列中的任务

Event Loop 执行顺序如下所示:

JavaScript中的Event Loop是用来管理异步代码执行的机制。

它确保了代码运行的顺序和正确性。下面是Event Loop的大致执行顺序:

  1. 执行同步代码:从上到下依次执行JavaScript代码中的同步部分。

  2. 处理微任务(Microtasks): 当遇到微任务时,会将微任务添加到一个微任务队列中。常见的微任务包括Promise回调函数、MutationObserver和process.nextTick。在当前宏任务执行完毕后,会依次执行微任务队列中的所有微任务,直到队列为空。

  3. 执行宏任务(Macrotasks): 当所有微任务执行完毕后,会检查是否有宏任务需要执行。常见的宏任务包括setTimeout、setInterval、requestAnimationFrame、I/O操作和事件回调。从宏任务队列中取出一个任务执行,执行完毕后返回步骤2。

  4. 重复步骤2和步骤3: 不断循环执行步骤2和步骤3,直到没有待处理的微任务和宏任务。

需要注意的是,微任务具有更高的优先级,会在下一个宏任务执行之前被处理完毕。而宏任务则是按照添加的顺序执行。

同时,值得提及的是,不同的宿主环境(例如浏览器和Node.js)可能有一些差异,但大致的执行逻辑是相似的。

Event Loop的执行顺序可以简化为:同步代码 -> 微任务 -> 宏任务 -> 重复执行微任务和宏任务

这样的循环保证了JavaScript的并发性和响应性。

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

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

相关文章

【Linux】软件包管理器 yum | vim编辑器

前言: 软件包管理器 yum和vim编辑器讲解 文章目录 软件包管理器 yum编辑器-vim四种模式普通模式批量化注释和批量化去注释末行模式临时文件 软件包管理器 yum yum&#xff08;Yellowdog Updater, Modified&#xff09;是一个在基于 RPM&#xff08;管理软件包的格式和工具集合&…

电影《社交网络》带来的深层次的思考

《社交网络》是由大卫芬奇执导&#xff0c;杰西艾森伯格、安德鲁加菲尔德、贾斯汀汀布莱克等主演的剧情片&#xff0c;于2010年10月8日在美国上映。该片讲述了马克扎克伯格和埃德华多萨瓦林两人如何建立和发展Facebook的故事。 学习关键点&#xff1a; 创业精神&#xff1a;电…

C++opencv图像算数操作-加减乘除

quick_opencv.h #include<opencv2\opencv.hpp> using namespace cv; class QuickDemo{public:void operators_demo(Mat &image);//图像算数操作 };QuickDemo.cpp #include<quick_opencv.h>//图像算数操作 void QuickDemo::operators_demo(Mat &image) {M…

八、计算机视觉-边界填充

文章目录 前言一、原理二、具体的实现 前言 在Python中使用OpenCV进行边界填充&#xff08;也称为zero padding&#xff09;是一种常见的图像处理操作&#xff0c;通常用于在图像周围添加额外的像素以便进行卷积或其他操作。下面是使用OpenCV进行边界填充的基本原理和方法 一…

解决elementUI固定列后,下方多了一条横线的问题

最近遇到一个bug,如下图,el-table的操作列使用fixed属性固定后,下方多了一条横线: 我们将样式设置高优先,以覆盖内联样式,如下是less里使用穿透样式解决的办法: <style lang="less" scoped> /deep/ .el-table__fixed-right {height: 100

vulvhub-----Hacker-KID靶机

打靶详细教程 1.网段探测2.端口服务扫描3.目录扫描4.收集信息burp suite抓包 5.dig命令6.XXE漏洞读取.bashrc文件 7.SSTI漏洞8.提权1.查看python是否具备这个能力2.使用python执行exp.py脚本&#xff0c;如果提权成功&#xff0c;靶机则会开放5600端口 1.网段探测 ┌──(root…

用户中心 -- 快捷键使用

一、后端&#xff0c;软件 idea 1.1 代码如何写出 网址&#xff1a;用户管理 --汇总 -- 明细-CSDN博客 1.2 一键调整代码格式的快捷键 网址&#xff1a; 用户管理第2节课 -- idea 2023.2 创建表--【本人】-CSDN博客

OpenCV DNN 活体检测项目环境配置等各阶段tips

date: 2020-09-22 14:53 资料来源《OpenCV深度学习应用与性能优化实践》第八章。 在复现这个项目的时候发现一些可以调整的小tips。 环境配置阶段 使用conda 创建python 工作环境时&#xff0c;注释掉requirems.txt 里的opencv-python-inference-engine4.1.2.1&#xff0c;安…

php美女写真视频管理源码 PHPCMS视频写真管理系统源码

国内首家CMS视频写真管理系统&#xff01; 三大模块&#xff0c;视频模块&#xff0c;图片模块&#xff0c;资讯模块。 全方面解决了多元素运营方案。采用CI框架核心开发&#xff0c;体积小、运行快&#xff0c;强大缓存处理。 视频采用了云转码服务将不同的视频来源、不同的…

强化学习(TD3)

TD3——Twin Delayed Deep Deterministic policy gradient 双延迟深度确定性策略梯度 TD3是DDPG的一个优化版本&#xff0c;旨在解决DDPG算法的高估问题 优化点&#xff1a; ①双重收集&#xff1a;采取两套critic收集&#xff0c;计算两者中较小的值&#xff0c;从而克制收…

KMS密钥管理有哪些安全功能

KMS(Key Management Service)密钥管理服务是一种专门用于管理和保护加密密钥的系统。在现代的信息安全领域中&#xff0c;密钥的重要性不言而喻&#xff0c;它是确保数据加密、解密以及身份验证等安全操作的核心要素。KMS的出现&#xff0c;极大地提高了密钥管理的效率和安全性…

跨境云手机如何简化tiktok运营流程

如今&#xff0c;tiktok已经成为世界范围内都非常流行的社交媒体平台。然而在大多数情况下&#xff0c;由于网络原因&#xff0c;tiktok无法在国内使用&#xff0c;但依然有越来越多的人注册tiktok号码、建立tiktok矩阵。原因是tiktok仍然有大量的流量可供商业使用&#xff0c;…

CSP-201812-1-小明上学

CSP-201812-1-小明上学 解题思路 #include <iostream> using namespace std; int main() {int red, yellow, green, n, timeSum 0;cin >> red >> yellow >> green;cin >> n;for (int i 0; i < n; i){int flag, time;cin >> flag &g…

Spark---环境搭建---入门概念

目录 环境搭建 测试 Apache Spark是用于大规模数据处理的统一分析引擎&#xff1b; spark 仅仅替代了hadoop的mapraduce&#xff1b; spark比hadoop快一百倍&#xff1b; 环境搭建 1&#xff1a;解压&#xff1b; 2&#xff1a;配置spark环境变量&#xff1a; vim /etc/pro…

WouoUI-PageVersion 一个用于快速构建具有丝滑OLED_UI动画的项目

WouoUI-PageVersion 写在前面 简介&致谢 Air001的TestUI例子的b站的演示视频 Air001的LittleClock例子的b站演示视频: https://www.bilibili.com/video/BV1J6421g7H1/ Stm32的TestUI例子的b站演示视频: https://www.bilibili.com/video/BV1mS421P7CZ/ 所有演示的工程文…

【6-1】使用hanlp进行实体抽取以及句法分析(问题待解决)

1.使用hanlp抽取法人名称、企业名称等信息 # -*- coding: utf-8 -*- from pyhanlp import *text1"1998年11月11日&#xff0c;马化腾和同学张志东在广东省深圳市正式注册成立“深圳市腾讯计算机系统有限公司”&#xff0c;之后许晨晔、陈一丹、曾李青相继加入。当时公司…

缩小ppt文件大小的办法

之前用别人模版做了个PPT&#xff0c;100多M,文件存在卡顿问题 解决办法&#xff1a; 1.找到ppt中哪个文件过大&#xff0c;针对解决 2.寻找视频/音频文件&#xff0c;减少体积 3.字体文件是不是过多的问题。 一、文件寻找的内容步骤&#xff1a; 步骤&#xff1a; 1.把p…

MySQL数据库基础(九):SQL约束

文章目录 SQL约束 一、主键约束 二、非空约束 三、唯一约束 四、默认值约束 五、外键约束&#xff08;了解&#xff09; 六、总结 SQL约束 一、主键约束 PRIMARY KEY 约束唯一标识数据库表中的每条记录。主键必须包含唯一的值。主键列不能包含 NULL 值。每个表都应该有…

【Pygame手册03/20】用于绘制形状的 pygame 模块

目录 一、说明二、画图函数2.1 接口draw下的函数2.2 pygame.draw.rect()2.3 pygame.draw.polygon()2.4 pygame.draw.circle()2.5 pygame.draw.ellipse()2.6 pygame.draw.arc()2.7 pygame.draw.line ()2.8 pygame.draw.lines()2.9 pygame.draw.aaline()2.10 pygame.draw.aaline…

java之VO,BO,PO,DO,DTO

概念 VO&#xff08;View Object&#xff09;&#xff1a;视图对象&#xff0c;用于展示层&#xff0c;它的作用是把某个指定页面&#xff08;或组件&#xff09;的所有数据封装起来。DTO&#xff08;Data Transfer Object&#xff09;&#xff1a;数据传输对象&#xff0c;这…