JavaScript 事件流

news2024/11/25 16:21:16

文章目录

  • JavaScript 事件流
    • 概述
    • 事件冒泡
      • 简介
      • onclick() 事件冒泡
      • addEventListener() 事件冒泡
      • stopPropagation() 阻止事件冒泡
    • 事件捕获
      • 简介
      • addEventListener() 事件捕获
      • W3C标准事件流
    • 取消事件默认行为
      • 取消使用对象属性绑定的事件的默认行为
      • 取消使用addEventListener()绑定的事件的默认行为
    • 案例
      • 利用事件冒泡实现分享功能

JavaScript 事件流

概述

事件流描述的是从页面中接受事件的顺序。IE和Netscape开发团队提出了两个截然相反的事件流概念,IE的事件流是事件冒泡(event bubbling),Netscape的事件流是事件捕获(event capturing)。

事件冒泡

简介

事件冒泡:当一个元素接收到事件时,会把它接收到的事件逐级向上传播给它的祖先元素,一直传到顶层的window对象。

顶层对象不同浏览器有可能不同,如IE9及以上版本、FireFox、Chrome、Safari等浏览器,事件冒泡的顶层对象为window对象,而IE7/8顶层对象则为document对象。

在这里插入图片描述

说明:当用户点击了<div>元素,这时click事件将按照<div> -> <body> -> <html> -> document -> window的顺序进行传播。

可以把事件冒泡比喻为水中的气泡,从水底冒出水面,也就是从下向上开始传播。

onclick() 事件冒泡

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<style>
			div {
				padding: 30px;
			}

			#div1 {
				background: red;
			}

			#div2 {
				background: green;
			}

			#div3 {
				background: blue;
			}
		</style>
		<script>
			window.onload = function() {
				//获取各个元素
				var oBody = document.getElementById('body1');
				var oDiv1 = document.getElementById('div1');
				var oDiv2 = document.getElementById('div2');
				var oDiv3 = document.getElementById('div3');
				//对各个元素的单击事件绑定事件处理函数fn1
				window.onclick = fn1;
				document.onclick = fn1;
				oBody.onclick = fn1;
				oDiv1.onclick = fn1;
				oDiv2.onclick = fn1;
				oDiv3.onclick = fn1

				function fn1() { //定义事件处理函数
					console.log(this);
				}
			};
		</script>
	</head>
	<body id="body1">
		<div id="div1">
			<div id="div2">
				<div id="div3"></div>
			</div>
		</div>
	</body>
</html>

点击div3元素,打印信息如下:

在这里插入图片描述

说明:onclick单击事件会实现事件冒泡,因此div3元素会首先触发单击事件,所触发的事件仍然会逐级向上传递。

addEventListener() 事件冒泡

addEventListener()方法的第三个参数为false事,为事件冒泡;为true时,为事件捕获。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<style>
			div {
				padding: 30px;
			}

			#div1 {
				background: red;
			}

			#div2 {
				background: green;
			}

			#div3 {
				background: blue;
			}
		</style>
		<script>
			window.onload = function() {
				var oDiv1 = document.getElementById('div1');
				var oDiv2 = document.getElementById('div2');
				var oDiv3 = document.getElementById('div3');
				//调用addEventListener()实现事件冒泡
				oDiv1.addEventListener('click', fn1, false);
				oDiv2.addEventListener('click', fn1, false);
				oDiv3.addEventListener('click', fn1, false);

				function fn1() {
					console.log(this);
				}
			};
		</script>
	</head>
	<body id="body1">
		<div id="div1">
			<div id="div2">
				<div id="div3"></div>
			</div>
		</div>
	</body>
</html>

点击div3元素,打印信息如下:

在这里插入图片描述

说明:div1、div2和div3元素均使用第三个参数为false的addEventListener()绑定事件函数,因而这3个元素将实现事件冒泡。在Chrome浏览器中运行后,当单击div3时,div3作为事件冒泡的最低层元素,会首先触发单击事件,然后div3逐级向上传递单击事件给div2和div1。

stopPropagation() 阻止事件冒泡

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<style>
			#div1 {
				width: 150px;
				height: 150px;
				line-height: 150px;
				text-align: center;
				border: 1px solid silver;
				margin: auto;
				display: none;
			}
		</style>
		<script>
			window.onload = function() {
				var oBtn = document.getElementById("btn");
				var oDiv = document.getElementById("div1");
				oBtn.onclick = function(e) {
					e.stopPropagation(); //阻止事件冒泡
					oDiv.style.display = "block";
				};
				document.onclick = function(e) {
					oDiv.style.display = "none";
				};
			};
		</script>
	</head>
	<body>
		<input id="btn" type="button" value="弹出">
		<div id="div1">
			hello world
		</div>
	</body>
</html>

在这里插入图片描述

事件捕获

简介

事件捕获是由Netscape Communicator团队提出来的,从最顶层的window对象开始逐渐往下传播事件,即最顶层的window对象最早接收事件,最低层的具体被操作的元素最后接收事件。

在这里插入图片描述

说明:当点击了<div>元素,采用事件捕获,则click事件将按照window -> document -> <html> -> <body> -> <div>的顺序传播。

addEventListener() 事件捕获

使用addEventListener()绑定事件函数时,当第三个参数取值为true时,将执行事件捕获,除此之外的其他事件的绑定方式,都是执行事件冒泡。

因此,只有标准浏览器才能进行事件捕获。

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			div {
				padding: 40px;
			}

			#div1 {
				background: red;
			}

			#div2 {
				background: green;
			}

			#div3 {
				background: blue;
			}
		</style>
		<script>
			window.onload = function() {
				var oDiv1 = document.getElementById('div1');
				var oDiv2 = document.getElementById('div2');
				var oDiv3 = document.getElementById('div3');
				//事件捕获
				oDiv1.addEventListener('click', fn1, true);
				oDiv2.addEventListener('click', fn1, true);
				oDiv3.addEventListener('click', fn1, true);
				window.addEventListener('click', fn1, true);
				document.addEventListener('click', fn1, true);
				//定义事件函数
				function fn1() {
					console.log(this);
				}
			};
		</script>
	</head>
	<body>
		<div id="div1">
			<div id="div2">
				<div id="div3"></div>
			</div>
		</div>
	</body>
</html>

点击div3元素,打印信息如下:

在这里插入图片描述

W3C标准事件流

W3C标准事件流包含3个阶段,捕获阶段、目标阶段、冒泡阶段。

在捕获阶段,事件对象通过目标的祖先从窗口传播到目标的父级。

在目标阶段,事件对象到达事件对象的事件目标。

在冒泡阶段,事件对象以相反的顺序通过目标的祖先传播,从目标的父级开始,到窗口结束。

W3C事件模型中发生的任何事件,先从顶层对象window开始一路向下捕获,直到达到目标元素,其后进入目标阶段。目标元素div接收到事件后开始冒泡到顶层对象window。例如,当用户单击了<div>元素,则首先会进行事件捕获,此时事件按window→document→<html>→<body>的顺序进行传播,当事件对象传到<div>时进入目标阶段,接着事件对象又从目标对象传到body,从而进入事件的冒泡阶段,此时事件对象按<body>→<html>→document→window的顺序传播事件。

在这里插入图片描述

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			div {
				padding: 40px;
			}

			#div1 {
				background: red;
			}

			#div2 {
				background: green;
			}

			#div3 {
				background: blue;
			}
		</style>
		<script>
			window.onload = function() {
				var oDiv1 = document.getElementById('div1');
				var oDiv2 = document.getElementById('div2');
				var oDiv3 = document.getElementById('div3');
				//标准事件流处理事件
				oDiv1.addEventListener('click', function() {
					console.log('事件冒泡1');
				}, false);
				oDiv1.addEventListener('click', function() {
					console.log('事件捕获1');
				}, true);
				oDiv2.addEventListener('click', function() {
					console.log('事件冒泡2');
				}, false);
				oDiv2.addEventListener('click', function() {
					console.log('事件捕获2');
				}, true);
				oDiv3.addEventListener('click', function() {
					console.log('事件捕获3');
				}, true);
				oDiv3.addEventListener('click', function() {
					console.log('事件冒泡3');
				}, false);
			};
		</script>
	</head>
	<body>
		<div id="div1">
			<div id="div2">
				<div id="div3"></div>
			</div>
		</div>
	</body>
</html>

点击div3元素,打印信息如下:

在这里插入图片描述

取消事件默认行为

事件的默认行为指的是:当一个事件发生时,浏览器自己会默认做的事情。这些事件的默认行为,在某些情况下,可能并不是我们所期望的,此时就需要取消它。事件默认行为的取消方法跟事件的绑定方式有关。

一、使用对象的事件属性绑定事件(即使用“obj.on事件名称=事件处理函数”的绑定格式)的事件默认行为的取消方法是:在当前事件的处理函数中return false即可阻止当前事件的默认行为。

二、使用addEventListenter()绑定事件函数的事件默认行为的取消方法是:在当前事件的处理函数中使用event.preventDefault()即可阻止当前事件的默认行为。

取消使用对象属性绑定的事件的默认行为

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title>取消使用对象属性绑定的事件的默认行为</title>
		<script>
			window.onload = function() {
				var oBtn = document.getElementById('btn');
				oBtn.onclick = function() {
					var name = document.getElementById("username");
					if (name.value.length == 0) {
						alert("请输入姓名");
						return false; //用户名没有输入时,阻止表单提交
					}
				};
			};
		</script>
	</head>
	<body>
		<form action="new_file.html">
			姓名: <input type="text" name="username" id="username" />
			<input type="submit" value="提交" id='btn' />
		</form>
	</body>
</html>

取消使用addEventListener()绑定的事件的默认行为

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title>取消使用addEventListener()绑定的事件的默认行为</title>
		<script>
			window.onload = function() {
				var oBtn = document.getElementById('btn');
				oBtn.addEventListener('click', function(ev) {
					var ev = ev || event;
					var name = document.getElementById("username");
					if (name.value.length == 0) {
						alert("请输入姓名");
						if (ev.preventDefault) { //用户名没有输入时,阻止表单提交
							ev.preventDefault();
						}
					}
				}, false);
			};
		</script>
	</head>
	<body>
		<form action="new_file.html">
			姓名: <input type="text" name="username" id="username" />
			<input type="submit" value="提交" id='btn' />
		</form>
	</body>
</html>

案例

利用事件冒泡实现分享功能

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title>使用事件冒泡实现"分享"功能</title>
		<style>
			#div1 {
				width: 80px;
				height: 150px;
				border: black 1px solid;
				position: absolute;
				left: -82px;
				top: 100px;
			}

			#div2 {
				width: 30px;
				height: 70px;
				position: absolute;
				right: -30px;
				top: 45px;
				background: black;
				color: white;
				text-align: center;
			}

			ul {
				list-style: none;
				padding: 0 20px;
			}

			img {
				width: 36px;
				height: 39px;
			}
		</style>
		<script>
			window.onload = function() {
				var oDiv = document.getElementById('div1');
				oDiv.onmouseover = function() { //鼠标光标移入,使div1显示
					this.style.left = '0px';
				}
				oDiv.onmouseout = function() { //鼠标光标移出,使div1隐藏
					this.style.left = '-82px';
				}
			};
		</script>
	</head>
	<body>
		<div id="div1">
			<ul>
				<a href="#">
					<li><img src="img/apple_pic.png" /></li>
				</a>
				<a href="#">
					<li><img src="img/banana_pic.png" /></li>
				</a>
				<a href="#">
					<li><img src="img/cherry_pic.png" /></li>
				</a>
			</ul>
			<div id="div2">分享到</div>
		</div>
	</body>
</html>

a b

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

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

相关文章

社科院与杜兰大学金融管理硕士项目你有了解吗?每年招生一期错过申请太可惜了

社科院与杜兰大学金融管理硕士是个什么项目&#xff1f;社科院是所学校吗&#xff0c;怎么都没听说过。杜兰大学又是哪里的学校&#xff1f;前几天有位咨询的同学抛出这些疑问&#xff0c;着实让我不知如何给予回答。像社科院这么低调的院校太少了。社科院全称是中国社会科学院…

错题 5jxn 8253,neg指令,知CPU频率求经典总线周期,如何取一个字,字扩展指令CBW扩展要求,知道相对位移量求转移后指令偏移地址

1&#xff1a;8253工作于方式1时&#xff0c;输出负脉冲的宽度等于() A:计数初值N-1个CLK脉冲宽度 B:计数初值N1个CLK脉冲宽度C:计数初值N个CLK脉冲宽度 D:计数初值(2N-1)/2个CLK脉冲宽度 方式0和方式1 波形相同&#xff08;计数过程中低&#xff0c;计数完高&#xff09;&…

Pytorch 暂退法(Dropout)

在2014年&#xff0c;斯里瓦斯塔瓦等人 (Srivastava et al., 2014) 就如何将毕晓普的想法应用于网络的内部层提出了一个想法&#xff1a; 在训练过程中&#xff0c;他们建议在计算后续层之前向网络的每一层注入噪声。 因为当训练一个有多层的深层网络时&#xff0c;注入噪声只会…

八、Gtk4-GtkBuilder and UI file

1 New, Open and Save button 在上一节中&#xff0c;我们制作了一个非常简单的编辑器。它在程序开始时读取文件&#xff0c;在程序结束时将文件写出来。它可以工作&#xff0c;但不是很好。如果我们有“新建”、“打开”、“保存”和“关闭”按钮就更好了。本节介绍如何在窗口…

【年度总结】2022不忘初心,砥砺前行 2023纵有疾风起,人生不言弃。

2022 工作 砥砺前行 跨境电商跑路 2022年3月&#xff0c;从一家小跨境电商被动跑路&#xff0c;果断处于迷茫期&#xff0c;被动跑路的最好优势就是有赔偿&#xff0c;哈哈&#xff0c;怎么还有一丢丢高兴呢。简单总结了下在该公司的经历&#xff0c;是之前的老大带我去的&am…

如何通过产品帮助中心减轻客服压力,提高内部人员工作效率

客户的问题一直在重复&#xff0c;客服人员压力山大 客户不愿接听客服电话&#xff0c;产品问题难以解决 下班时间休息日&#xff0c;产品问题找谁问&#xff1f; 这些关于客户服务的老问题们困扰着许多产品方多年 要解决以上问题&#xff0c;更好地满足顾客需求。 搭建帮…

基于javaweb(springboot+mybatis)生活美食分享平台管理系统设计和实现以及文档报告

基于javaweb(springbootmybatis)生活美食分享平台管理系统设计和实现以及文档报告 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎…

详解函数指针(●‘◡‘●)☞

本文紧接于http://t.csdn.cn/78wbF 这篇一.函数指针数组\ ( >O< ) /1.书写形式&#xff1a;由函数指针内部*变量名>*变量名[n]&#xff1b; 2.使用&#xff1a;函数指针数组的用途&#xff1a;转移表 例如&#xff1a;模拟计算器&#xff1a;#include<stdio.h> …

用了这么久 IDEA,你还没用过 Live Templates 吗?

大家好&#xff0c;我是风筝&#xff0c;公众号「古时的风筝」&#xff0c;专注于 Java技术 及周边生态。 Live Templates 是什么&#xff0c;听上去感觉挺玄乎的。有的同学用过之后觉得简直太好用了&#xff0c;不能说大大提高了开发效率吧&#xff0c;至少也是小小的提高一下…

Qt创建项目:手把手创建第一个Qt项目

上一节介绍了QtCreator编辑器的页面长什么样子&#xff0c;以及都有哪些功能区&#xff0c;每个功能区都是用来做什么的。这一节我就手把手带大家创建一个Qt项目。 创建项目 点击新建按钮 创建项目有两个入口&#xff0c;一个是在欢迎页面的projects中点击New(新建)按钮&…

未来,勒索软件会呈现何种发展态势?

尽管过去一年里&#xff0c;全世界大约花费了1500亿美元在网络安全领域上&#xff0c;却无法真正阻止黑客攻击。在过去一年里&#xff0c;针对医院、学校、政府的勒索软件越来越多&#xff1b;加密货币领域也有无休止的黑客盗窃事件&#xff1b;还有针对微软、英伟达、Rockstar…

CORS跨域通信

在上一集的坐牢文章中&#xff0c;我们介绍了非官方的很多中方案&#xff0c;其中不乏一些江湖秘术。今天的这个&#xff0c;绝对的正统&#xff0c;纯正的官方打造。我们赶紧来看看。 1.什么是CORS&#xff1f; CORS 是一个 W3C 标准&#xff0c;全称是“跨域资源共享”&…

Prometheus的使用

Prometheus 是一个开放性的监控解决方案&#xff0c;用户可以非常方便的安装和使用 Prometheus 并且能够非常方便的对其进行扩展。 在Prometheus的架构设计中&#xff0c;Prometheus Server 并不直接服务监控特定的目标&#xff0c;其主要任务负责数据的收集&#xff0c;存储并…

ArcGIS Engine基础(31)之使用仿射变换对矢量数据进行空间校正

在生产数据过程中&#xff0c;因每个工程项目都可能有自己的施工坐标系&#xff0c;难免会产生数据提供方与数据使用方采用的坐标系不一致&#xff0c;造成数据在不同坐标系下存在一定偏移、旋转、缩放等&#xff0c;为了让数据能够在新坐标系准确定位&#xff0c;需要进行空间…

kitti数据集理解及可视化

kitti数据集简介 kitti数据集是比较早出来的3D检测方面的数据集&#xff0c;相对来说数据结构简单&#xff0c;适合做单目检测的工作&#xff0c;目前也是业界和学术界常用的公开数据集。 自己最近也在做单目3D检测的工作&#xff0c;所以也分享一些理解&#xff0c;希望能给到…

微服务自动化管理【Docker跨主机集群之Flannel】

环境说明 CentOS7 etcd-v3.4.3-linux-amd64.tar.gz flannel-v0.11.0-linux-amd64.tar.gz 官方文档&#xff1a;https://github.com/coreos/flannel 下载地址&#xff1a;https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz 1.…

verilog学习笔记- 9)流水灯实验

目录 简介&#xff1a; 实验任务&#xff1a; 硬件设计&#xff1a; 程序设计&#xff1a; 下载验证&#xff1a; 简介&#xff1a; LED&#xff0c;又名发光二极管。LED 灯工作电流很小&#xff08;有的仅零点几毫安即可发光&#xff09;&#xff0c;抗冲击和抗震性能好&…

工业互联网安全漏洞分析

声明 本文是学习github5.com 网站的报告而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 研究背景 在政策与技术的双轮驱动下&#xff0c;工业控制系统正在越来越多地与企业内网和互联网相连接&#xff0c;并与新型服务模式相结合&#xff0c;逐步形成…

day01--Python学习笔记之安装及测试

目录 官网下载 1、Python自带简单的开发环境 2、Python的交互式命令行程序 3、官方技术文档 4、安装模块文档 1、Python自带简单的开发环境 在当前中编辑代码 在新文件中编辑代码 2、P…

springboot 使用tomcat详解

1.使用内嵌tomcat启动 创建tomcat对象设置端口设置Context设置servlet 和 路径 2.spring中单独注册servlet和地址的映射关系 Beanpublic ServletRegistrationBean getServletRegistrationBean() {ServletRegistrationBean bean new ServletRegistrationBean(apiServlet);bean…