Javascript事件

事件

js操作css称为校本化的css,js与html交互通过事件完成。
事件就是文档或浏览器窗口中发生一些特定的交互瞬间。
事件流 ------>事件传播
事件流描述的是从页面中接收事件的顺序。
事件流的历史:
浏览器发展到第四代的时候!IE团队和美国网景公司浏览器开发团队想到的问题。
单击事件不仅仅发生在按钮上,其实单击了整个页面。
IE和Netscape 提出了相反的事件流
在IE中提出的事件流想法是冒泡流, 当我们在网页操作或点击这个div ,它会往它的父级上去传播。
在Netscape中提出的事件流想法是事件捕获流,当我们在网页上操作或点击div的时候!它会往body和html上进行层级传递。

事件冒泡流

概念:事件开始时!由最具体的元素接收,然后逐级向父级元素(上级)传播!交给不具体的节点(文档)。

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			background-color: red;
			width: 200px;
			height: 200px;
		}
	</style>
</head>
<body>
		<div id="box">
			
		</div>
		<script type="text/javascript">
			var box = document.getElementById("box");
			box.onclick = function(){
				box.innerHTML = 'div\n';
			}
			document.body.onclick = function(){
				box.innerHTML += 'body\n';
			}
			document.documentElement.onclick = function(){
				box.innerHTML += 'document\n';
			}
			window.onclick = function(){
				box.innerHTML += 'window\n';
			}
		</script>
</body>
</html>

事件冒泡的传递方向: div ----> body ----> html ----> document ----> window
注意事项:IE9以上 一直冒泡到window对象。 IE8会有一些问题。

事件捕获流

概念:事件发生时!由不太具体的节点更早的接收事件,而最具体的节点应该最后接收事件。

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			background-color: red;
			width: 200px;
			height: 200px;
		}
	</style>
</head>
<body>
		<div id="box">
			
		</div>
		<script type="text/javascript">
			var box = document.getElementById("box");
			//事件捕获  addEventListener() 第三个参数为false代表冒泡阶段!为true代表捕获阶段
			box.addEventListener('click',function(){
				box.innerHTML += 'box\n';
			},true);
			document.body.addEventListener('click',function(){
				box.innerHTML += 'body\n'
			},true);
			document.documentElement.addEventListener('click',function(){
				box.innerHTML += 'document\n';
			},true)
			window.addEventListener('click',function(){
				box.innerHTML += 'window\n';
			},true);
		</script>
</body>
</html>

在事件流中发生了三个阶段:并分为事件捕获阶段,处于目标阶段,事件冒泡阶段。

事件处理程序

说白了就是事件的绑定函数。
事件处理程序分为HTML事件处理程序、DOM0级事件处理程序、DOM2级事件处理程序、IE事件处理程序。

HTML事件处理程序

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
	</style>
</head>
<body>
	//html事件处理程序
		<div id="box" style="width:200px;height:100px;background-color: pink;" onclick="this.innerHTML +="></div>
		<script type="text/javascript">
			
		</script>
</body>
</html>

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
	</style>
</head>
<body>
	//html事件处理程序
		<div id="box" style="width:200px;height:100px;background-color: pink;" onclick="test()"></div>
		<script type="text/javascript">
			function test(){
				console.log(this);
				this.innerHTML += '1';
			}
			
		</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
	</style>
</head>
<body>
	//html事件处理程序
		<div id="box" style="width:200px;height:100px;background-color: pink;" onclick="this.innerHTML += event.type"></div>
		<script type="text/javascript">
			function test(){
				document.getElementById("box").innerHTML += '1';
			}
			
		</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
	</style>
</head>
<body>
	//html事件处理程序
		<button id="box"  value="xxxx" style="width:200px;height:100px;background-color: pink;" onclick="this.innerHTML += value;"></button>
		<script type="text/javascript">
			function test(){
				document.getElementById("box").innerHTML += '1';
			}
			
		</script>
</body>
</html>

缺点: HTML时间处理程序 是html+js无分离!后期不易维护。

DOM0级事件处理程序

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
	</style>
</head>
<body>
	//DOM0级事件处理程序
		<div id="box"></div>
		<script type="text/javascript">
			var box = document.getElementById("box");
			box.onclick = function(){
				
			}
		</script>
</body>
</html>

优点:简单、具有跨浏览器的优势。
缺点:只能绑定一个事件的处理程序,不能给同一个元素绑定相同的事件处理程序,如果绑定了会有覆盖现象事件处理程序不会被删除。需要手动关闭页面来清除内存。

DOM2级事件处理程序

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width: 200px;
			height: 200px;
			background-color: red;
		}
	</style>
</head>
<body>
	//DOM2级事件处理程序
		<div id="box"></div>
		<script type="text/javascript">
		//布尔值默认为false是处于冒泡阶段,为true是处于捕获阶段。
		//addEventListner(事件名,处理程序的函数,布尔值)
		//优点:不会像0级事件处理程序发生覆盖现象。
		//缺点:IE8浏览器不支持2级事件处理程序的。
		var box = document.getElementById("box");
		box.addEventListener('click',function(){
			this.innerHTML += 1;
		},false);
		box.addEventListener('click',function(){
			this.innerHTML += 2;
		},false);
		</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width: 200px;
			height: 200px;
			background-color: red;
		}
	</style>
</head>
<body>
	//DOM0级事件处理程序
		<div id="box"></div>
		<script type="text/javascript">
		//布尔值默认为false是处于冒泡阶段,为true是处于捕获阶段。
		//addEventListner(事件名,处理程序的函数,布尔值)
		//优点:不会像0级事件处理程序发生覆盖现象。
		//缺点:IE8浏览器不支持2级事件处理程序的。
		var box = document.getElementById("box");
		//监听函数传参,可以用匿名函数来包装一个监听函数。
		box.addEventListener('click',function(){
			test(123);
		},false);
		function test(x){
			alert(x);
		}
		</script>
</body>
</html>

DOM2级事件处理程序移除事件

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width: 200px;
			height: 200px;
			background-color: red;
		}
	</style>
</head>
<body>
	//DOM0级事件处理程序
		<div id="box"></div>
		<script type="text/javascript">
		var box = document.getElementById("box");
		//添加事件的监听者
		function handler(){
			this.innerHTML += 1;
		}
		box.addEventListener('click',handler,false);
			
		//正确移除事件的方式
		BOX.removeEventListener('click',handler,false);
		
		</script>
</body>
</html>

IE事件处理程序

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width: 200px;
			height: 200px;
			background-color: red;
		}
	</style>
</head>
<body>
	//DOM0级事件处理程序
		<div id="box"></div>
		<script type="text/javascript">
		//IE attachEvent()  detachEvent()
		var box = document.getElementById("box");
		//IE11不支持。IE8不支持this
		box.attachEvent('onclick',function(){
			this.innerHTML += 1;
		},false);
		</script>
</body>
</html>

解决IE8中this无法使用的问题

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width: 200px;
			height: 200px;
			background-color: red;
		}
	</style>
</head>
<body>
	//DOM0级事件处理程序
		<div id="box"></div>
		<script type="text/javascript">
		//IE attachEvent()  detachEvent()
		var box = document.getElementById("box");
		box.attachEvent('onclick',function(){
			//只能用元素对象 不能使用this
			box.innerHTML += 1;
		},false);
		</script>
</body>
</html>

优点:IE9以上支持相同事件处理程序对同一个元素进行事件处理不会发生覆盖现象,数据会以正向的方式展示。
IE8支持相同事件处理程序对同一个元素进行事件处理,不会发生覆盖现象,但是数据是以倒序的形式展示。

IE事件处理程序移除事件

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width: 200px;
			height: 200px;
			background-color: red;
		}
	</style>
</head>
<body>
	//DOM0级事件处理程序
		<div id="box"></div>
		<script type="text/javascript">
		//IE attachEvent()  detachEvent()
		var box = document.getElementById("box");
		function handler(){
			box.innerHTML += 1;
		}
		box.attachEvent('onclick',handler);
		box.detachEvent('onclick',handler);
		</script>
</body>
</html>

事件绑定兼容写法

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width: 200px;
			height: 200px;
			background-color: red;
		}
	</style>
</head>
<body>
	<button type="button" id="btn">你过来啊</button>
	<script type="text/javascript">
		//DOM2级事件处理程序  addEventListener()  IE8不支持。 ie提供了attachEvent()做兼容
		var btn = document.getElementById("btn");
		//btn.attachEvent('onclick',fn,false);
		addEvent(btn,'click',function(){
			console.log(this.innerHTML);
		})
		function addEvent(target,eventType,handler){
			if(target.addEventListener){
				//chrome ff safari
				target.addEventListener(eventType,handler,false);
			}else{
				target.addEvent('on'+eventType,handler,false);
			}
		}
	</script>
</body>
</html>

改变this指向

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width: 200px;
			height: 200px;
			background-color: red;
		}
	</style>
</head>
<body>
	<button type="button" id="btn">你过来啊</button>
	<script type="text/javascript">
		//DOM2级事件处理程序  addEventListener()  IE8不支持。 ie提供了attachEvent()做兼容
		var btn = document.getElementById("btn");
		//btn.attachEvent('onclick',fn,false);
		addEvent(btn,'click',function(){
			console.log(this.innerHTML);
		})
		function addEvent(target,eventType,handler){
			if(target.addEventListener){
				//chrome ff safari
				target.addEventListener(eventType,handler,false);
			}else{
				target.addEvent('on'+eventType,handler,false);
			}
		}
		console.log(this)l//window
		var obj = {
			innerHTML: 'XXX';
		}
		function fn(){
			console.log(this.innerHTML);
		}
		//call 方法可以改变this指向问题
		fn.call(obj);
	</script>
</body>
</html>

事件的调用顺序

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
		<style>
			#box{
				width: 200px;
				height: 200px;
				background-color: green;
			}
		</style>
</head>
<body>
	<div id="box" onclick="this.innerHTML += 'html\n'"></div>
	<script type="text/javascript">
		var box = document.getElementById("box");
		//DOM0级
		box.onclick = function(){
			this.innerHTML +='DOM0级\n'
		}
		//DOM2级
		if(box.addEventListener){
			box.addEventListener('click',function(){
				this.innerHTML += 'DOM2级\n'
			},false)
		}
		//IEbox.
		if(box.attachEvent){
			box.attachEvent('click',function(){
				this.innerHTML += 'ie\n'
			},false)
		}
	</script>
</body>
</html>

总结: 相同点: 如果同时出现HTML事件处理程序和DOM0级事件处理程序。DOM0级会覆盖HTML事件处理程序。
不同点: chrome safari fixfox浏览器以及IE11寄过 DOM0级DOM2级
IE9 IE10 结果为DOM0级 DOM2级 IE
IE8 结果为DOM0级 IE

事件对象

如何获取事件对象

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width: 100px;
			height: 100px;
			background-color: red;
		}
	</style>
</head>
<body>
	<div id="box"></div>
	<script type="text/javascript">
		//如何获取事件对象
		//事件目标
		//事件代理
		//事件冒泡
		//事件流阶段  eveentPhase
		//取消默认事件
		//兼容性
		window.onload = function(){
			var box = document.getElementById("box");
			//event对象时时间处理对象的第一个参数 ie8不兼容
			box.onclick = function(e){
				box.innerHTML += e;
			}
		}
		//可以直接使用event变量
		box.onclick = function(){
			this.innerHTML += event;
		}
		//兼容写法
		box.onclick = function(e){
			e = e || event;
			this.innerHTML  = e;
		}
	</script>
</body>
</html>

时间目标对象

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width: 100px;
			height: 100px;
			background-color: red;
		}
	</style>
</head>
<body>
	<ul id="box">
		<li class="item">1</li>
		<li class="item">2</li>
	</ul>
	<script type="text/javascript">
		//currentTarget   target和srcElement
		var box = document.getElementById("box");
		box.onclick = function(e){
			e = e || window.event;
			console.log(e);
			var items = document.getElementsByTagName('li');
			items[0].innerHTML = e.currentTarget;
			
		}
	</script>
</body>
</html>

target属性

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width: 100px;
			height: 100px;
			background-color: red;
		}
	</style>
</head>
<body>
	<ul id="box">
		<li class="item">1</li>
		<li class="item">2</li>
	</ul>
	<script type="text/javascript">
		//currentTarget   target和srcElement
		//currentTarget属性返回事件当前所在的节点,正在执行的监听函数所绑定的节点。
		var box = document.getElementById("box");
		/*box.onclick = function(e){
			e = e || window.event;
			console.log(e);
			var items = document.getElementsByTagName('li');
			items[0].innerHTML = e.currentTarget;
			
		}
		*/
	   //target属性
	   box.onclick = function(){
		   e = e|| window.event;
		   console.log(e.target);
	   }
	</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width: 100px;
			height: 100px;
			background-color: red;
		}
	</style>
</head>
<body>
	<ul id="box">
		<li class="item">1</li>
		<li class="item">2</li>
	</ul>
	<script type="text/javascript">
		//currentTarget   target和srcElement
		//currentTarget属性返回事件当前所在的节点,正在执行的监听函数所绑定的节点。
		var box = document.getElementById("box");
		/*box.onclick = function(e){
			e = e || window.event;
			console.log(e);
			var items = document.getElementsByTagName('li');
			items[0].innerHTML = e.currentTarget;
			
		}
		*/
	   //target属性返回的是事件的实际目标对象
	   box.onclick = function(e){
		   e = e|| window.event;
		   console.log(e.target);
		   console.log(e.target==this);
		   //this对象跟e.currentTarget属性是一致的。
		   console.log(e.currentTarget==this);
	   }
	</script>
</body>
</html>

事件代理

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin: 0;
		}
		ul{
			list-style: none;
			overflow: hidden;
			margin-top: 80px;
		}
		ul li{
			float:left;
			width:100px;
			height:30px;
			line-height:30px;
			color:#fff;
			background-color: #000;
			margin:0 10px;
			
		}
	</style>
</head>
<body>
	<ul id="box">
		<li>1</li>
		<li>2</li>
		<li>3</li>
		<li>4</li>
		<li>5</li>
	</ul>
	<script type="text/javascript">
		window.onload = function(){
			//1.常规方法实现
			//获取标签
			var lis = document.getElementsByTagName('li');
			for(var i = 0; i < lis.length; i++){
				lis[i].onmousemover = function(){
					this.style.backgroundColor = 'blue';
				}
				lis[i].onmouseout = function(){
					this.style.backgroundColor = 'blank';
				}

			}
			
		}
		//事件代理的方式实现
		var box = document.getElementById("box");
		box.onmousemover = function(e){
			e = e || window.event;
			var target = e.target || e.srcElement;
			target.style.backgroundColor = 'blue';
		}
		box.onmouseout = function(e){
			e = e|| window.event;
			var target = e.target || e.srcElement;
			target.style.backgroundColor = 'green';
		}
	</script>
	
</body>
</html>

给未来事件绑定代理

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin: 0;
		}
		ul{
			list-style: none;
			overflow: hidden;
			margin-top: 80px;
		}
		ul li{
			float:left;
			width:100px;
			height:30px;
			line-height:30px;
			color:#fff;
			background-color: #000;
			margin:0 10px;
			
		}
	</style>
</head>
<body>
	<ul id="box">
		<li>1</li>
		<li>2</li>
		<li>3</li>
		<li>4</li>
		<li>5</li>
	</ul>
	<script type="text/javascript">
		//给未来的元素绑定事件,使用事件代理
		var box = document.getElementById("box");
		box.onmousemover = function(e){
			e = e || window.event;
			var target = e.target || e.srcElement;
			target.style.backgroundColor = 'blue';
		}
		box.onmouseout = function(e){
			e = e || window.event;
			var target = e.target || e.srcElement;
			target.style.backgroundColor = 'blank';
		}
	</script>
	
</body>
</html>

事件冒泡
bubbles
canceBubble
stopPropagation
stopImmediatePropagation

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin: 0;
		}
		ul{
			list-style: none;
			overflow: hidden;
			margin-top: 80px;
		}
		ul li{
			float:left;
			width:100px;
			height:30px;
			line-height:30px;
			color:#fff;
			background-color: #000;
			margin:0 10px;
			
		}
	</style>
</head>
<body>
	<button type="button" id="btn" style="height:300px;width: 200px;">按钮</button>
	<input type="text" name="" id="text" value="" />
	<script type="text/javascript">
		//bubbles返回的是一个布尔值  表示当前事件是否会冒泡.只读
		//大部分事件都会冒泡!但是focus blur scroll 事件不会冒泡
	var btn = document.getElementById('btn');
	var test = document.getElementById("text");
	btn.onclick = function(e){
		e = e || window.event;
		console.log(e.bubbles);
	} 
	test.onfocus = function(e){
		e = e || window.enent;
		console.log(e.bubbleds);
	}
	
	
	//stopPropagation()表示取消事件的进一步冒泡!无返回值
	//缺点 无法阻止同一事件的其他的监听函数被调用。
	//ie8不支持
	btn.onclick = function(e){
		e = e || window.event;
		//阻止冒泡
		e.stopPropagation();
		this.innerHTML = '阻止冒泡';
	}
	document.body.onclick = function(e){
		e = e || window.event;
		console.log('body');
	}
	
	</script>
	
</body>
</html>
<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin: 0;
		}
		ul{
			list-style: none;
			overflow: hidden;
			margin-top: 80px;
		}
		ul li{
			float:left;
			width:100px;
			height:30px;
			line-height:30px;
			color:#fff;
			background-color: #000;
			margin:0 10px;
			
		}
	</style>
</head>
<body>
	<button type="button" id="btn" style="height:300px;width: 200px;">按钮</button>
	<input type="text" name="" id="text" value="" />
	<script type="text/javascript">
		//bubbles返回的是一个布尔值  表示当前事件是否会冒泡.只读
		//大部分事件都会冒泡!但是focus blur scroll 事件不会冒泡
	var btn = document.getElementById('btn');
	var test = document.getElementById("text");
	btn.onclick = function(e){
		e = e || window.event;
		console.log(e.bubbles);
	} 
	test.onfocus = function(e){
		e = e || window.enent;
		console.log(e.bubbleds);
	}
	
	
	//stopPropagation()表示取消事件的进一步冒泡!无返回值
	//缺点 无法阻止同一事件的其他的监听函数被调用。
	//ie8不支持
	btn.onclick = function(e){
		e = e || window.event;
		//阻止冒泡
		e.stopPropagation();
		this.innerHTML = '阻止冒泡';
	}
	document.body.onclick = function(e){
		e = e || window.event;
		console.log('body');
	}
	//stopImmediatePropagation()表示取消事件的进一步冒泡!无返回值
	//缺点 无法阻止同一事件的其他的监听函数被调用。
	//ie8不支持
	btn.onclick = function(e){
		e = e || window.event;
		//阻止冒泡
		e.stopImmediatePropagation();
		this.innerHTML = '阻止冒泡';
	}
	btn.addEventListener('click',function(e){
		e = e || window.event;
		e.stopImmediatePropagation();
		this.innerHTML = '修改了'
	},false)
	document.body.onclick = function(e){
		e = e || window.event;
		console.log('body');
	}
	
	
	</script>
	
</body>
</html>

cancelBubble

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin: 0;
		}
		ul{
			list-style: none;
			overflow: hidden;
			margin-top: 80px;
		}
		ul li{
			float:left;
			width:100px;
			height:30px;
			line-height:30px;
			color:#fff;
			background-color: #000;
			margin:0 10px;
			
		}
	</style>
</head>
<body>
	<button type="button" id="btn" style="height:300px;width: 200px;">按钮</button>
	<input type="text" name="" id="text" value="" />
	<script type="text/javascript">
		//e.cancelBubble = true; 全浏览器都支持,不是标准写法
		var handler = function(e){
			e = e || window.event;
			if(e.stopPropagation){
				e.stopPropagation();
			}else{
				e.cancelBubble = true;
			}
		}
	</script>
	
</body>
</html>

事件流阶段

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
</head>
<body>
	<button id="btn">事件流</button>
	<script type="text/javascript">
		var btn = document.getElementById("btn");
		// e.eventPhase 0表示事件没有发生。1 表示捕获阶段 2 目标阶段 3 冒泡阶段
		btn.onclick = function(e){
			e = e || window.event;
			this.innerHTML = e.eventPhase + "阶段";
		}
		btn.addEventListener('click',function(e){
			e = e || window.event;
			this.innerHTML = e.eventPhase + "阶段";
		},true)
	</script>
	
</body>
</html>

取消默认行为

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
</head>
<body>
	<a href="javascript:void(0);" id="apeland">xxx</a>
	<a href="javascript:;">000</a>
	<script type="text/javascript">
		//事件对象中两个方法,阻止默认事件:preeventDefault() returnValue return false;
		var apeland = document.getElementById("apeland");
		apeland.onclick = function(e){
			e = e || window.event;
			//e.preventDefault();//此方法IE8浏览器不支持。阻止默认事件
			//阻止默认事件 ff ie8以上不支持
			//e.returnValue = false;
			this.innerHTML = 'asdada';
		}
		//兼容写法
		if(e.preventBubble){
			e.preventDefault();
		}else{
			e.returnValue = false;
		}
	</script>
</body>
</html>

阻止冒泡
e.stopPropagation
阻止默认事件
e.preventDefault
阻止默认事件
e.returnValue
技巧 return false能阻止默认事件
return false;
returnValue兼容IE8以下的浏览器

鼠标事件对象属性

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		#box{
			width:200px;
			height: 200px;
			background-color: red;
		}
	</style>
</head>
<body>
	<div id="box"></div>
	<script type="text/javascript">
		//坐标位置
		//事件对象中提供了clientX/Y, x/y  offsetX/Y  screenX/Y
		var box = document.getElementById("box");
		box.onmousemove = function(e){
			e = e || window.event;
			console.log(e);
			this.innerHTML = 'clientX:${e.clientX};clientY:${e.clientY};X:${e.x};Y:$(e.y);''
			this.innerHTML = 'screenX:${e.screenX};screenY:${e.screenY};';
			this.innerHTML = 'pageX:${e.pageX};pageY:${e.pageY};';
		}
		
	</script>
</body>
</html>

clientX、clientY 和 x、y相当于浏览器的x轴和y轴的距离
screenX、screenY 相当于显示器屏幕的x轴和y轴的距离

事件流
描述的是从页面接收事件的顺序
IE事件流失事件冒泡流
Netscape的事件流是事件捕获流

事件流阶段

  1. 事件捕获阶段
  2. 处于目标阶段
  3. 事件冒泡阶段

事件捕获阶段:从最不具体的节点 window、document接收事件 ,往具体的节点进行传播
事件冒泡阶段:从具体的节点进行接收事件,逐级往上传递到最不具体的节点
事件对象
e.eventPhase 描述事件发生的阶段
事件捕获阶段 1
处于目标阶段 2
事件冒泡阶段 3
事件处理程序

  1. HTML 事件处理程序

  2. DOM0级事件处理程序
    2.1 btn.onclick = function(e){
    e = e || window.event;
    }
    //有事件覆盖现象
    btn.onclick = function(e){
    e = e || window.event;
    }

  3. DOM2级事件处理程序
    btn.addEventListener('click',function(){},false);
    btn.removeEventListener('click'function(){},false)
    var handler = function(){
    ...
    }
    btn.addEventListener('click',handler,false);
    btn.removeEventListener('click',handler,false)

  4. IE事件处理程序
    btn.attachEvent('onclick',function(){
    //在ie中小心使用this!这个this指向window

    })

    btn.detachEvent('onclick'function(){

    })
    //处理this的指向问题

事件目标
e.currentTarget === this

e.target
e.srcElement
//兼容性代码
var target = e.target || e.secElement;

事件代理 也叫事件委托
//给未来的元素绑定事件,使用事件代理
var box = document.getElementById("box");
box.onmousemover = function(e){
e = e || window.event;
var target = e.target || e.srcElement;
target.style.backgroundColor = 'blue';
}

取消默认事件
e.preventDefault(); IE8浏览器不兼容

e.returnValue = false; IE8兼容

return false;

事件冒泡

e.bubbles
blur focus scroll 三个事件的返回值为false

e.stopPropagation(); 常用
e.stopImmediatePropagation;
e.cancleBubble = true;
阻止事件冒泡兼容性的写法

var hadler = function(e){
	e = e || window.event;
	(ife.stopPropagation){
		e.stopPropagation();
	}else{
		e.cancleBubble = true;
	}
}

事件对象汇总的属性 坐标位置
clientX clientY x y
相对于当前浏览器(有效的浏览器区域)的X轴和Y轴的距离

screenX screenY
相对于显示器屏幕的X轴和Y轴的距离

pageX pageY
相对于页面的x轴和y轴的距离,如果有滚动条 包含整个页面

offsetX offsetY
相对于事件源的x轴和Y轴的距离

放大镜案例

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
	<style type="text/css">
		*{
			padding: 0;
			margin: 0;
		}
		#box{
			width: 430px;
			height: 430px;
			bprder 1px solid #DDDDDD;
			position: relative;
			margin: 50px;
		}
		#small_box{
			width: 430px;
			height: 430px;
			position: relative;
		}
		#small_box #mask{
			position: absolute;
			width: 210px;
			height: 210px;
			background:url(放大镜图片) repeat;
			top: 0;
			left: 0;
			display: none;
		}
		#big_box{
			position: absolute;
			left:440px;
			top: 0;
			width: 430px;
			height: 430px;
			border 1px solid #ddd;
			overflow: hidden;
			display: none;
		}
		#big_box img{
			position: absolute;
			z-index: 5;
		}
	</style>
</head>
<body>
	<div id="box">
		<div id="small_box">
			<img src="小图片" alt="">
			<span id="mask">
				
			</span>
		</div>
		<div id="big_box">
			<img src="大图片" alt="">
		</div>
	</div>

	
	<script type="text/javascript">
		window.onload = function(){
			//获取需要的标签
			var box = document.getElementById("box");
			var small_box = box.children[0];
			var big_box = box.children[1];
			var small_img = small_box.children[0];
			var mask = small_box.children[1];
			var big_img = big_box.children[0];
			//监听鼠标移入
			small_box.onmousemover = function(){
				//让遮罩层和大图显示出来
				mask.style.display = "block";
				big_box.style.display = 'block';
				//监听鼠标移动
				small_box.onmousemove = function(){
					e = e || window.event;
					//求出小盒子移动的水平和垂直的距离
					var moveX = e.clientX - small_box.offsetLeft - box.offsetLeft - mask.offsetWidth * 0.5;
					var moveY =  e.clientY - small_box.offsetTop - box.offsetTop - mask.offsetHeight * 0.5;
					//边界处理
					if(moveX <0){
						moveX = 0;
					}else if(moveX >= small_box.offsetWidth - mask.offsetWidth){
						moveX = small_box.offsetWidth - mask.offsetWidth;
					}
					if(moveY <0){
						moveY = 0;
					}else if(moveY >= small_box.offsetHeight - mask.offsetHeight){
						moveY = small_box.offsetHeight - mask.offsetHeight;
					}
									
				
					//让小盒子移动起来
					mask.style.left = moveX + 'px';
					mask.style.top = moveY + 'px';
					//让大图移动起来
					//公司: moveX/大图移动的距离??? = (small_box宽度-mask宽度)/(big_img宽度-small_box宽度)
					var x = moveX / (small_box.offsetWidth - mask.offsetWidth);
					var y = moveY / (big_img.offsetWidth - big_box.offsetWidth);
					big_img.style.left = - x * (big_img.offsetWidth - big_box.offsetWidth) + 'px';
					big_img.style.top = - y * (big_img.offsetHeight - big_box.offsetHeight) + 'px';
				}
				small_box.onmouseout = function(){
					mask.style.display = 'none';
					big_box.style.display = 'none';
				}
			}
		}
		
	</script>
</body>
</html>
posted @ 2020-08-14 11:32  pythonliuwei  阅读(192)  评论(0编辑  收藏  举报