JavaScript中的事件

1 事件(Event)

事件也就是用户或者浏览器执行的某种动作,而JS与Html之间的交互是通过事件而来的。使用仅在事件发生时执行的**监听器(事件处理程序)**来订阅事件。web浏览器可以发生多种事件,在DOM3 Events定义了如下事件类型:

  • 用户界面事件(UIEvent):涉及与BOM交互的通用浏览器事件
  • 焦点事件(FocusEvent):在元素获得和失去焦点时触发
  • 鼠标事件(MouseEvent)
  • 滚轮事件(WheelEvent):使用鼠标滚轮时触发
  • 输入事件(InputEvent)
  • 键盘事件(KeyboardEvent)
  • 合事事件(CompositionEvent):在使用某种IME(Input Method Editor,输入法编辑器)输入字符时触发

1.1 事件处理程序

事件处理器(或事件监听器),就是来响应某个事件的函数。主要有HTML事件处理程序、DOM0事件处理程序和DOM2事件处理程序。

1.1.1 HTML事件处理程序

也就是直接将事件函数写在HTML元素的属性上,而所要执行的函数代码,实际上是通过JS引擎由eval()调用的,它是全局作用域。举个例子:

<button onclick="alert('hello,world')"></button>

同时它也可以写成这样:

<button onclick="printHello()"></button>
<script>function printHello() {alert(this)//object windowalert('hello,world');}
</script>

HTML事件处理程序有一定的缺点:

  1. 时机问题:比如当<script>中的js代码还没加载,就提前执行事件处理程序,会造成错误
  2. js与html强耦合:如果修改事件处理器,需要同时改js和html两个地方的代码
  3. 对事件处理程序作用链的扩展在不同浏览器中可能导致不同的结果

针对这些缺点,在实际的代码编写中,更多人选择JavaScript指定事件处理程序

1.1.2 DOM0事件处理程序

在传统的监听器处理方式中,一般把监听器赋值给DOM元素的一个事件处理程序属性(每个元素都有,比如onclick、onload等等),完全通过js代码来进行处理,这个时候btn是局部作用域,而且js和html代码也进行解耦,如下代码:

<button id="button">
<script>let btn = document.getElementById("button");btn.onclick=function(){alert(this);//object HTMLButtonElementalert('test DOM0 event function');}
</script>

但是同样也存在着一些问题:

  • 无法为一个onclick属性添加多个事件处理程序
  • 对于一个元素的事件处理程序属性,也无法轻易赋值事件处理程序(有可能会覆盖之前其他的事件处理程序)

所以针对这一点,DOM2做了一些相关的优化

1.1.3 DOM2事件处理程序

DOM2 Events为事件处理程序的增加了两个方法,这些方法暴露在所有的DOM节点上

  • addEventListener():事件处理程序赋值
  • removeEventListener():事件处理程序移除

此外它们接收三个参数:

  • 事件名:不同的事件的名称
  • 事件处理函数:事件处理程序实现
  • 一个布尔值:
    • true:代表捕获阶段调用事件处理程序
    • false:表示在冒泡阶段调用事件处理程序

因此对于DOM0中的代码,可以对一个DOM元素添加多个事件处理程序:

<button id="button">
<script>let btn = document.getElementById("button");btn.addEventListener("click", ()=>{alert('first button');},false);btn.addEventListener("click", ()=>{alert('second button');},true);
</script>

输出结果:先输出second button然后再输出first button
可以用removeEventListener()移除事件处理程序,这个时候就无法点击发生对应事件了:

<button id="button">
<script>let btn = document.getElementById("button");let test =function(){alert('test event function remove')};btn.addEventListener("click", test, false);btn.removeEventListener("click", test, false);
</script>

那么为何在addEventListener()添加多个事件处理程序时,不按照程序顺序输出?可以发现修改了输入参数的布尔值,通过不同阶段调用事件处理程序,能够得到不同的事件执行顺序,这就涉及到了事件流。

1.2 事件流

也就是描述页面接收事件的顺序,在早期不同的浏览器厂商对于事件流有不同的实现方案。IE的事件冒泡,Netscape的事件捕获。之后DOM2将事件流进行了统一(所有现代浏览器都支持DOM事件流,只有IE8及更早版本不支持

1.2.1 IE事件流-事件冒泡

事件被定义为从文档树最深节点到外部的节点:比如<div>---<body>---<html>---document
image.png

1.2.2 Netscape事件流-事件捕获

和事件冒泡相反,事件捕获是外部的节点到内部的节点。对于上面的节点,事件访问的顺序应该是:document---<html>---<body>---<div>。事件捕获实际上是为了在事件到达最终目标前拦截事件。
image.png

1.2.3 DOM事件流

1.2.3.1 0级DOM事件模型(非W3C事件模型)

也就是指W3C的DOM标准形成前的事件模型,也就是原始的添加事件监听函数的模型,W3C的DOM标准并不支持的事件模型,具体例子如下:

<!--html部分-->
<input id="myButton" type="button" value="Press Me" οnclick="alert('thanks')"><!-- js部分 -->
document.getElementById("myButton").onclick = function() {alert('thanks');
}
1.2.3.2 2级DOM事件模型

DOM1级于1998年10月1日成为W3C推荐标准,但是1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型。2级DOM中除了定义了一些DOM相关的操作之外还定义了一个事件模型 ,这个标准下的事件模型就是我们所说的2级DOM事件模型。
DOM2 事件规范规定了事件流分为三个阶段,会以如下顺序触发事件:

  • 事件捕获
  • 到达目标
  • 事件冒泡

以前面的例子,捕获阶段是从document --> html --> body,div阶段是到达目标阶段,然后事件再进行冒泡,反向传播到document。
image.png

1.2.3.3 3级DOM事件模型

DOM3级没有对事件做任何的修订,所以现代浏览器仍然沿用2级DOM事件标准

计算类型的任务,可以由CPU进行执行,但是对于一些IO操作,文件读写,这个时候CPU就闲置,因此可以执行其他的工作。
JavaScript是单线程的,同一时间只能是执行一个任务,也就是它只能执行计算类的操作,无法操作

1.3 事件对象

当DOM中发生事件时,所有相关信息都会被收集并存储在一个名为event的对象中。这个对象包含了一些基本信息,比如导致事件的元素、发生的事件类型,以及可能与特定事件相关的任何其他数据。这个对象就是事件对象

事件对象只要事件发生时才会 产生,不管是以哪种方式(DOM0或DOM2)指定事件处理程序,都会传入这个event对象。当所有事件处理程序结束后,事件对象就会被销毁。

<button id="button">
<script>let btn = document.getElementById("button");btn.addEventListener("click", (event)=>{alert(event.type);//"click"});
</script>

所有事件对象都有这些公共属性:
:::info

  • bubbles 布尔值,表示事件是否是冒泡类型
  • cancelable 布尔值,表示事件是否可以取消默认动作
  • currentTarget 当前目标元素,即添加当前事件处理程序的元素
  • target 实际目标元素,即实际触发事件的元素
  • type 返回当前事件的名称
  • eventPhase 事件传播的当前阶段,1表示捕获阶段
    :::
    公共方法主要有:
    :::info
  1. preventDefault() 通知浏览器不要执行该事件的默认动作,常用于阻止链接的跳转,表单的提交,等标签的默认行为
  2. stopPropagation() 冒泡阶段下,阻止事件的继续向上冒泡
    :::

1.4 事件委托

在JavaScript中,页面事件处理程序的数量与页面整体性能直接相关。所以在使用事件处理程序时,需要对过多的事件处理程序进行优化调整,比如事件委托。事件委托就是利用事件冒泡,使用一个事件处理程序来管理一种类型的事件。
事件委托是通过在所有元素的共同祖先节点添加一个事件处理程序,来达到管理多个事件类型的效果,比如:

<ul><li>列表项1</li><li>列表项2</li><li>列表项3</li>
</ul>
<script>var list=document.getElementsByTagName("li");for(i=0;i<list.length;i++){list[i].onclick=function(){alert("我是"+e.target);}}
</script>

就可以修改为处理祖先节点<li>元素,来统一管理该子元素下的多个事件处理程序

var ul=document.getElementById('ul');
ul.onclick=function(e){var e= e || window.event;var target = e.target || e.srcElement;if(target.nodeName.toLowerCase() === "li"){alert("我是"+e.target);}
}

2 事件循环(Event Loop)

在具体的代码执行中,JS引擎会常驻内存中,等待着宿主把JS代码或者函数传递给它执行。

在 ES3 和更早的版本中,JavaScript 本身还没有异步执行代码的能力,这也就意味着,宿主环境传递给 JavaScript 引擎一段代码,引擎就把代码直接顺次执行了,这个任务也就是宿主发起的任务。
但是,在 ES5 之后,JavaScript 引入了 Promise,这样,不需要浏览器的安排,JavaScript 引擎本身也可以发起任务了。

在JSC引擎的术语中,把宿主发起的任务称作为宏观任务;把JS引擎发起的任务称为微观任务。在操作系统中,通常等待的行为都是一个事件循环。所以JS没有自己的事件循环系统,它依赖浏览器的事件循环系统。

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

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

相关文章

【Linux】yum本地配置

配置将来是在干什么&#xff1f; yum会根据/etc/yum.repos.d/该路径下面的配置文件&#xff0c;来构成自己的下载路径&#xff0c;&#xff08;根据OS版本&#xff0c;根据你要下载的软件&#xff09;&#xff0c;yum帮助我们下载&#xff0c;安装 一般的机器&#xff0c;内置…

10.常用统计分析方法——主成分分析和因子分析

基础知识&#xff1a; 主成分分析概念 主成分分析PCA&#xff1a;是一种数据降维的技巧&#xff0c;将大量相关变量转化为一组很少的不相关变量&#xff0c;这些无关变量称为主成分。 在特征选择方法中有一种方法是方差过滤&#xff0c;即如果一个特征的方差很小&#xff0c…

强化学习:MuJoCo机器人强化学习仿真入门(1)

声明&#xff1a;我们跳过mujoco环境的搭建&#xff0c;搭建环境不难&#xff0c;可自行百度 下面开始进入正题&#xff08;需要有一定的python基础与xml基础&#xff09;&#xff1a; 下面进入到建立机器人模型的部分&#xff1a; 需要先介绍URDF模型文件和导出MJCF格式 介绍完…

Flink中的时间和窗口(时间语义,水位线,窗口,迟到数据的处理)

目录 Flink中的时间和窗口 1时间语义 1.1Flink中的时间语义 1.1.1处理时间 1.1.2事件时间 1.2那种时间语义更重要 2 水位线 2.1 事件时间和窗口 2.2 什么是水位线 2.3 如何生成水位线 2.3.1使用WatermarkGenerator 2.3.2使用SourceFunction 2.4 水位线的传递 2.5 水位…

Adobe XD 55.2.12.2软件安装教程(附软件下载地址)

软件简介&#xff1a; 软件【下载地址】获取方式见文末。注&#xff1a;推荐使用&#xff0c;更贴合此安装方法&#xff01; Adobe XD 55.2.12.2是一款专业级的图形界面UI/UX设计工具&#xff0c;拥有丰富的功能和强大的性能。它集成了原型设计、界面设计和交互设计等多种功能…

面试篇-大厂的面试流程和面试注意事项

以前找工作的时候&#xff0c;对于流程中的面试总是好奇流程走到哪一步了&#xff0c;这一轮面试有没有通过&#xff0c;后面不通过还有没有消息通知等问题。今天作为一个求职者和面试官的身份来主要讲一下大厂招聘&#xff0c;内部的面试过程以及流转的流程是什么样的以及该注…

高性能跨平台网络通信框架 HP-Socket v5.9.5

项目主页 : http://www.oschina.net/p/hp-socket开发文档 : https://www.docin.com/p-4478351216.html下载地址 : https://github.com/ldcsaa/HP-SocketQQ Group: 44636872, 663903943 v5.9.5 更新 一、主要更新 问题修复&#xff1a;由于 v5.9.4 版本升级了 KCP 导致 UDP AR…

arcgis 线要素shp数据处理

回顾 上篇写了arcgis 点shp数据处理之少数点和批量点坐标如何生成点要素&#xff0c;这个可能在做一些设计及查询中需要做的第一步。那么今天将对如何点集转线、线要素编辑数据处理做一记录。 一、工具 arcToolbox工具箱、编辑器 二、操作方法 1.点集转线 还是用上篇处理成…

哪个牌子的洗地机质量好?值得入手的洗地机

在家庭清洁方面&#xff0c;洗地机绝不是被认为的智商税。实际上&#xff0c;洗地机是一种非常实用的清洁工具&#xff0c;其最大的优点在于能够高效地协助我们清理家居环境&#xff0c;不论是在何种场景下&#xff0c;都能有效提升卫生水平。然而&#xff0c;由于市场上存在众…

eNSP学习——理解ARP及Proxy ARP

目录 名词解释 实验内容 实验目的 实验步骤 实验拓扑 配置过程 基础配置 配置静态ARP 名词解释 ARP (Address Resolution Protocol)是用来将IP地址解析为MAC地址的协议。ARP表项可以分为动态和静态两种类型。   动态ARP是利用ARP广播报文&#xff0c;动态执行并自动进…

20240123-其实投资也不难

前几天团队聚餐&#xff0c;和老板们有聊到投资这个话题&#xff0c;其中一个观点很有趣&#xff0c;说是&#xff1a;“我们的服务器用的都是阿里云的&#xff0c;然后阿里云有一个跟我们对接的工作人员&#xff0c;通过我们买机器的数量增长&#xff0c;觉得我们公司发展应该…

《WebKit 技术内幕》学习之七(4): 渲染基础

4 WebKit软件渲染技术 4.1 软件渲染过程 在很多情况下&#xff0c;也就是没有那些需要硬件加速内容的时候&#xff08;包括但不限于CSS3 3D变形、CSS3 03D变换、WebGL和视频&#xff09;&#xff0c;WebKit可以使用软件渲染技术来完成页面的绘制工作&#xff08;除非读者强行…

图卷积网络(GCN)

本文主要分为两部分&#xff0c;第一部分介绍什么是GCN&#xff0c;第二部分将进行详细的数学推导。 一、什么是GCN 1、GCN 概述 本文讲的GCN 来源于论文&#xff1a;SEMI-SUPERVISED CLASSIFICATION WITH GRAPH CONVOLUTIONAL NETWORKS&#xff0c;这是在GCN领域最经典的论文…

无刷电机学习-方波电调 电路篇

想要彻底的理解无刷电机的驱动&#xff0c;那必然少不了学习他的驱动电路和程序。这里用开源的AM32无刷电调&#xff08;方波驱动&#xff09;来作为学习无刷电机笔记。 https://github.com/AlkaMotors附上作者github地址 AM32_Hardware: 基于AT32MCU的AM32PCB另一位大佬开源…

niushop靶场漏洞查找-文件上传漏洞等(超详细)

实战漏洞-niushop 一.端口扫描 http://www.xxx.com/index.php?s/admin/login 这里查询到后面的url有且仅有一个&#xff0c;目测估计是后台 访问url 发现确实是后台 二、找漏洞 Sql注入漏洞1&#xff1a; 点击进去 修改id www.xxx.com/index.php?s/goods/goodslist&…

网络要素服务(WFS)详解

文章目录 1. 概述2. GetCapabilities3. DescribeFeatureType4. GetFeature4.1 Get访问方式4.2 Post访问方式 5. Transaction5.1 Insert5.2 Replace5.3 Update5.4 Delete 6 注意事项 1. 概述 前置文章&#xff1a; 地图服务器GeoServer的安装与配置 GeoServer发布地图服务&#…

C语言爬虫采集图书网站百万数据

最近需要查阅一些资料&#xff0c;只给到相关项目名称以及关键词&#xff0c;想通过图书文库找到对应书籍&#xff0c;那么怎么才能在百万数据库中找到自己需要的文献呢&#xff1f; 今天我依然用C语言写个爬虫程序&#xff0c;从百万数据库中查找到适合的文章&#xff0c;能节…

【GitHub项目推荐--Go语言学习指南】【转载】

Go语言学习指南是一份涵盖大部分 Golang 程序员所需要掌握的核心知识&#xff0c;拥有 Go语言教程、Go开源书籍、Go语言入门教程、Go语言学习路线。零基础学习 Go语言、Go编程&#xff0c;首选 GoGuide。 地址&#xff1a;https://github.com/coderit666/GoGuide

方法(java)

方法&#xff08;method&#xff09;是程序中最小的执行单元 实际开发中&#xff0c;重复的代码、具有独立功能的代码可以抽取到方法中 实际开发中&#xff0c;方法的好处&#xff1a; 1.可以提高代码的复用性 2.可以提高代码的可维护性 方法定义&#xff1a;把一些代码打…

【设计模式】美团三面:你连装饰器都举不出例子?

什么是装饰器模式&#xff1f; 装饰器模式&#xff0c;这个设计模式其实和它的名字一样&#xff0c;非常容易理解。 想象一下&#xff0c;每天出门的时候&#xff0c;我们都会思考今天穿什么。睡**衣、睡裤加拖鞋&#xff0c;还是西装、领带加皮鞋&#xff1f;又或者说是&…