js事件(3)

1<html>
<head>
	<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
	<title>JS事件</title>
	<script src="http://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
	<style>
		div{
			width:300px;
			border:1px solid blue;
			padding:10px;
		}
	</style>
</head>
<body>
	<!-- 事件代理 -->
	<ul id="nav">
		<li>111</li>
		<li>222</li>
		<li>333</li>
		<li>444</li>
	</ul>

	<!-- 测试事件冒泡 -->
	<div id="div1" style="height:100px;">
		<div id="div2" style="width:280px;height:80px;">
			<div id="div3" style="width:260px;height:60px;">
				<input id="btn1" type="button" value="事件冒泡" />
			</div>
		</div>
	</div>

	<br />

	<!-- 测试事件捕获 -->
	<div id="div4" style="height:100px;">
		<div id="div5" style="width:280px;height:80px;">
			<div id="div6" style="width:260px;height:60px;">
				<input id="btn2" type="button" value="事件捕获" />
			</div>
		</div>
	</div>
</body>
</html>

<script type="text/javascript">
	//兼容ie浏览器测试
	var console = console || {};
	console.log = console.log || function(a){
		alert(a);
	}

	/*
	事件代理,听起来有点高大上,其实比较屌丝.
	*/

	/*
	每注册一个事件,都会需要耗费一点内存,理论上注册的事件越多,可能会越卡.
	根据事件的冒泡特性,给目标元素的父元素注册事件,这种方式就是事件的代理.
	*/

	var ul = document.getElementById("nav");
	//给ul绑定事件
	ul.onclick = function(evt){
		evt = evt || event;
		//currentTarget始终是监听事件者,而target是事件的真正响应元素
		var ele = evt.target;
		var text = ele.innerHTML;
		//只要再这里根据获取到不同的li,做不用的处理,就可以通过一个事件处理多个元素事件.
		console.log(text);
	}

	/*
	简单的事件代理就这样了,通常需要用事件代理的元素有ul,table等.
	比起事件代理,更有意思的是js事件的捕获,冒泡原理.

	js的事件并不是点击某个地方,然后某个地方就响应事件,js事件是以事件流的形式存在的.
	就是说当你点击了某个地方,网页的最外层document或者window会先捕获到事件,
	然后根据元素的父子层级一级一级网上捕获,直到点击的目标元素,
	然后从目标元素一级一级再往回冒泡,直接最外层document或者window.
	不同浏览器捕获事件的最外层对象不一致,这不要紧,因为网页的可视范围都是body内.
	所以接下来我们都当做事件都是从body开始(这是错的哈,理解就好).
	*/


	//给所有的div都注册点击事件
	var div = document.getElementsByTagName("div");
	for(var i = 0,len = div.length; i < len; i++){
		div[i].onclick = function(evt){
			evt = evt || event;
			var ele = evt.currentTarget;
			var id = ele.id;
			ele.style.border = "1px solid red";
			//alert可以暂停js运行进程,可以更直观的看到事件冒泡流程.
			alert("暂停一下,点击事件冒泡到了" + id);
		};
	}
	//注册按钮点击事件
	var btn1 = document.getElementById("btn1");
	btn1.onclick = function(evt){
		evt = evt || event;
		var ele = evt.currentTarget;
		ele.style.border = "1px solid red";
		alert("暂停一下,目标按钮响应了事件.");
	}

	/*
	点击事件冒泡按钮,事件先后响应了btn -> div3 -> div2 -> div1.
	这就是事件冒泡的过程,从目标对象根据层级关系一级一级往外冒泡.
	这也从侧面反应了一个问题,直接在属性上绑定是事件是响应的冒泡阶段.
	*/

	/*
	事件捕获流程
	*/

	//给所有的div都注册在捕获阶段响应事件
	var div = document.getElementsByTagName("div");
	for(var i = 0,len = div.length; i < len; i++){
		if(document.addEventListener){
			div[i].addEventListener("click",function(evt){
				evt = evt || event;
				var ele = evt.currentTarget;
				var id = ele.id;
				ele.style.border = "1px solid red";
				//alert可以暂停js运行进程,可以更直观的看到事件冒泡流程.
				alert("暂停一下,点击事件被" + id + "捕获到了.");
			},true);//传入true,响应捕获事件
		}
	}

	//注册捕获按钮点击事件
	var btn2 = document.getElementById("btn2");
	if(document.addEventListener){
		btn2.addEventListener("click",function(evt){
			evt = evt || event;
			//阻止事件冒泡
			//evt.stopPropagation();

			var ele = evt.currentTarget;
			ele.style.border = "1px solid red";
			alert("暂停一下,目标按钮响应了事件.");
		},true);
	}

	/*
	点击事件捕获按钮,事件先后响应了div4 -> div5 -> div6 -> btn2.
	但是事件并没有停,会继续响应冒泡过程btn2 -> div6 -> div5 -> div4.
	这就是js事件流的整个过程,先是目标元素最外层的元素/对象捕获到事件,然后一级一级往内捕获,
	直到目标元素,然后从目标元素在一级一级的往外冒泡到最外层元素/对象.
	事件代理就是利用了事件的冒泡过程,给目标元素父元素注册事件,然后通过子元素冒泡到父元素.
	*/

	/*
	如果要阻止事件的冒泡过程,不同的浏览器方法不同.
	标准的w3c使用event.stopPropagation().
	ie使用event.cancelBubble = true;就可以了.

	需要区分一下preventDefault()和stopPropogation()的区别,
	preventDefault()是用来阻止浏览器的默认行为,比如点击a会跳转,滚动鼠标滑轮页面会滚动等.
	在ie下return false = stopPropagation() + preventDefault().
	*/

	/*
	知识点:
	1.事件流就是事件的捕获->目标->冒泡整个过程.
	2.需要绑定大量事件对象的对象,可以使用事件代理优化效率.
	3.事件流是可以阻止的.
	*/
</script>

 

你可能感兴趣的:(js)