事件流(事件冒泡和捕获,函数闭包等)

事件流

事件流描述的是从页面中接受事件的顺序,当几个都具有事件的元素层叠在一起的时候,那么你点击其中一个元素,并不是只有当前被点击的元素会触发事件,而层叠在你点击范围的所有元素都会触发事件。

事件流包括两种模式:冒泡和捕获

事件捕获:

父级元素先触发,子集元素后触发;(由外到内)

事件冒泡:

子集元素先触发,父级元素后触;(由内到外)

子集元素和父元素具备同样的事件,当触发子元素时,也会触发父元素的事件。

事件冒泡和事件捕获实例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>事件冒泡和事件捕获</title>
		<style type="text/css">
			#bigDiv{
				width: 400px;
				height: 400px;
				border: 1px solid #000;
			}
			#innerDiv{
				width: 200px;
				height: 200px;
				border: 1px solid #AFEEEE;
			}
		</style>
		<script type="text/javascript">
			window.onload=function(){
				var bigDiv=document.getElementById('bigDiv');
				var innerDiv=document.getElementById('innerDiv');
				var arr=[bigDiv,innerDiv,document,document.body];
				for (var i=0;i<arr.length;i++) {
				//传统方式
//					arr[i].onclick=function(){
//						console.log(this);
//					}
				//通过Dom的经典方式添加事件
//					addEventListener(参数1,参数2,参数3)
//					参数1表示的是事件的类型   click,load,mousedown,blur,focus
//					参数2表示的是事件的处理程序
//					参数3表示的是事件是否冒泡  true/false
				//表示的是事件的冒泡  设置值为false
					arr[i].addEventListener('click',show,false);
				//表示的是事件的捕获  设置值为true
//					arr[i].addEventListener('click',show,true);
				}
				function show(){
					console.log(this);
				}
			}
		</script>
	</head>
	<body>
		<div id="bigDiv">
			<div id="innerDiv">
			</div>
		</div>
	</body>
</html>

通过Dom的经典方式添加事件

addEventListener(参数1,参数2,参数3)
参数1表示的是事件的类型 click,load,mousedown,blur,focus
参数2表示的是事件的处理程序
参数3表示的是事件是否冒泡 true/false

事件冒泡测试结果(由内到外)
在这里插入图片描述

事件捕获测试结果(由外到内)
在这里插入图片描述

事件兼容

(1)事件绑定

addEventListener 用于注册事件处理程序,IE 中为 attachEvent。

addEventListener 是 DOM 中的标准内容

//语法结构
element.addEventListener(event, function, useCapture)
//通过Dom的经典方式添加事件
//		addEventListener(参数1,参数2,参数3)
//		参数1表示的是事件的类型   click,load,mousedown,blur,focus
//		参数2表示的是事件的处理程序
//		参数3表示的是事件是否冒泡  true/false
//		注意:不要使用 "on" 前缀。 例如,使用 "click" ,而不是使用 "onclick"。
//		可以使用函数名,来引用外部函数

事件绑定实例一

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>事件绑定</title>
		<script type="text/javascript">
			window.onload=function(){
				var btn=document.getElementById('txt');
			//匿名函数
//				btn.addEventListener('click',function(){
//					alert('事件注册了');
//				})
			//有名函数
				btn.addEventListener('click',show);
			//下面这个有名函数放在window里面或外面都OK
				function show(){
					alert('事件注册了');
				}
			}
		</script>
	</head>
	<body>
		<input type="button" id="txt" value="事件注册(事件绑定)" />
	</body>
</html>

事件绑定实例二

通过 addEventListener(添加点击事件监听器)形式的绑定事件不会互相抵消,从而实现一个按钮控制多个事件

(2)事件移除

**removeEventListener()**移除事件监听器(不能使用匿名函数)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>事件绑定和移除</title>
		<script type="text/javascript">
			window.onload=function(){
			//获取页面元素button
				var	btn2=document.getElementById('btn2');
			//注册事件处理程序	addEventListener()
				btn2.addEventListener('click',show);
			//移除事件监听器		removeEventListener()
//				btn2.removeEventListener('click',show);
			//下面这个有名函数放在window里面或外面都OK
				function show(){
					console.log('第一个事件');
					console.log('第二个事件');
				}
			}
		</script>
	</head>
	<body>
		<button id="btn2">按钮2</button>
	</body>
</html>

上面代码事件绑定测试结果为:
在这里插入图片描述

(3)获取事件对象

事件对象封装了事件发生的详细信息,尤其是鼠标、键盘事件。如鼠标事件发生的位置、键盘事件的键盘键等。

IE 中的事件对象:IE 中的事件对象是一个隐式可用的全局对象:event,它是 window对象的一个属性。

标准 DOM 的事件对象:在标准 DOM 浏览器检测发生了某个事件时,将自动创建一个 Event对象,并隐式地将该对象作为事件处理函数的第一个参数传入

案例一:

返回事件目标的名称 使用属性tagName

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>事件对象</title>
		<script type="text/javascript">
			window.onload=function(){
				var btn=document.getElementById('btn');
				btn.ondblclick=Myheader;
				function Myheader(e){
					if(window.event){
						e=window.event;
					}
				//兼容低版本的IE浏览器
				var MyIE;
				if(e.srcElement){
					MyIE=e.srcElement;
				}else{
					MyIE=e.target;
				}
			//返回事件目标的名称	使用属性tagName
				alert(MyIE.tagName);
				}
			}
			
		</script>
	</head>
	<body>
		<button id="btn">请双击我</button>
	</body>
</html>

上面代码事件绑定测试结果为:
在这里插入图片描述

案例二(常用鼠标事件对象)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>常用鼠标事件对象</title>
		<style type="text/css">
			#leftDIV{
				width: 200px;
				height: 200px;
				background: pink;
				float: left;
			}
			#rightDIV{
				width: 200px;
				height: 200px;
				border: 1px solid #000;
				float: left;
				overflow: auto;
			}
		</style>
	</head>
	<body>
		<div id="leftDIV"></div>
		<div id="rightDIV"></div>
		<script type="text/javascript">
//			var MyMouse=document.getElementById('leftDIV');
			var MyMouse=document.getElementById('leftDIV');
			var txt=document.getElementById('rightDIV');
			MyMouse.onclick=Myheader;
			MyMouse.ondblclick=Myheader;
			MyMouse.onmouseleave=Myheader;
			MyMouse.onmousedown=Myheader;
			MyMouse.onmouseup=Myheader;
			function Myheader(OEvent){
				if(window.event){
					OEvent=window.event;
				}
				txt.innerHTML+=OEvent.type+'\n';
			}
		</script>
	</body>
</html>

上面代码事件绑定测试结果为:
在这里插入图片描述

(4)阻止冒泡

event.stopPropagation() 阻止事件冒泡的产生

阻止冒泡案例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>阻止事件冒泡</title>
		<style>
			#bigDIV{
				width: 400px;
				height: 400px;
				border: 20px solid greenyellow;
				position: relative;
			}
			#innerDIV{
				width: 200px;
				height: 200px;
				border: 20px solid orangered;
				position: absolute;
				left: 80px;
				top: 80px;
			}
			#span{
				display: inline-block;
				background: pink;
				margin: 90px 9px;
			}
		</style>
	</head>
	<body>
		<div id="bigDIV">
			<div id="innerDIV">
				<span id="span">这里是最里面的span标签</span>
			</div>
		</div>
		<script type="text/javascript">
			var bigDIV=document.getElementById('bigDIV');
			var innerDIV=document.getElementById('innerDIV');
			var span=document.getElementById('span');
		//有名函数
//			bigDIV.addEventListener('click',show,false);
//			innerDIV.addEventListener('click',show,false);
//			span.addEventListener('click',show,false);
//			function show(event){
//				alert(this);
//			//阻止事件冒泡的产生	event.stopPropagation()
//				event.stopPropagation();
//			}
		//匿名函数
			bigDIV.addEventListener('click',function(event){
				alert('你点击了最外面的div');
				event.stopPropagation();
			},false);
			innerDIV.addEventListener('click',function(event){
				alert('你点击了第二层的div');
				event.stopPropagation();
			},false);
			span.addEventListener('click',function(event){
				alert('你点击了最里面的span标签');
				event.stopPropagation();
			},false);
		</script>
	</body>
</html>

(5)阻止默认

w3c 的方法是 e.preventDefault()

IE 则是使用 e.returnValue =false;

preventDefault 它是事件对象(Event)的一个方法,作用是取消一个目标元素的默认行为。比如超链接a

	<body>
		<a href="事件冒泡.html" target="_blank">啦啦啦啦啦</a>
		<script type="text/javascript">
			var a1=document.getElementsByTagName('a')[0];
		//传统用法阻止事件的默认发生
//			a1.onclick=function(e){
//				e.preventDefault();
//			}
		//使用DOM方法来阻止默认发生
			a1.addEventListener('click',show);
		//兼容
			function show(e){
				if (e.preventDefault) {
					e.preventDefault();
				} else{
					window.event.returnValue=false;
				}
			}
		</script>
	</body>

函数闭包

闭包是指有权限访问另一个函数作用域中的变量的函数。在 javascript 语言中,闭包就是函数和该函数作用域的组合。从这个概念上来讲,在 js 中,所有函数都是闭包(函数都是对象并且函数都有和他们相关联的作用域链 scope chain),但是嵌套的函数闭包作用会更大。

嵌套函数:

js中特殊的作用域链,父对象的所有变量对子对象都是可见的,反之则不成立。

闭包的应用(两大作用)

①读取函数内部的变量

②就是让这些变量的值始终保持在内存中

案例一

		<script type="text/javascript">
		//闭包是指有权限访问另一个函数作用域中的变量的函数
		// 闭包就是函数和该函数作用域的组合
		//在js中,所有函数都是闭包(函数都是对象且函数都有他们相关联的作用域链),但是嵌套的函数闭包作用会更大。
		//函数的嵌套:
			//js中特殊的作用域链:
			//父对象的所有变量,对子对象都是可见的,反之则不成立。
				function PiKaQiu(){
					var color='yellow';
					var weight=30;
					var height=20;
					function PiKaQiu_01(){
						alert(color);
					}
					PiKaQiu_01();
				}
				PiKaQiu();
				
			//使用return
				function cat(){
					var color='white';
					var height=20;
					var weight=50;
					function cat_01(){
						return color;
					}
					return cat_01();
				}
				alert(cat());
		</script>

案例二

		<script type="text/javascript">
			function cat(){
				var color='橘黄色';
				var height='又矮又胖';
				var weight='大肥猫';
				function cat_01(){
					return '这是一只'+color+'的而且'+height+'的'+weight;
				}
				return cat_01();
			}
//			alert(cat());
			function Person(){
				alert(cat());
			}
			Person();
		//闭包函数的两大作用:
			//1、可以读取函数内部的变量
			//2、让变量的值始终保持在内存中
		</script>

案例二代码测试结果为:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/a_lllll/article/details/85001383
今日推荐