`
cxy020
  • 浏览: 61467 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

js事件(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>
	</style>
</head>
<body>
	<!-- 最简单的注册事件 -->
	<input id="btn0" type="button" value="click" onclick="btnClick();" />
	<!-- 属性绑定事件 -->
	<input id="btn1" type="button" value="click1" />
	<!-- 使用addEventListener/attachEvent注册事件 -->
	<input id="btn2" type="button" value="click2" />

	<input id="btn3" type="button" value="click3" />

	<!-- 测试删除事件 -->
	<input id="btn4" type="button" value="click4" />
	<!-- 测试removeEventListener/detachEvent删除事件 -->
	<input id="btn5" type="button" value="click5" />
</body>
</html>

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

	/*
	js是一门事件驱动的语言,我们平常的开发都跟事件息息相关.
	也就是说js事件是js与浏览器交互的主要途径.
	给dom注册事件的方法有至少3种,各种都有所区别.
	*/

	/*
	直接通过元素事件属性绑定事件,这个是最简单最粗暴的方法了.
	*/
	function btnClick(){
		console.log("btn click!");
	}

	/*
	一般不建议使用这种方法,因为这样会让代码的耦合度边高.
	当函数名称需要修改的时候,就必须修改html和js两块代码.
	*/

	/*
	直接在dom属性上绑定事件.
	*/
	var btn1 = document.getElementById("btn1");
	//绑定事件
	btn1.onclick = function(evt){
		//ie触发事件后,没有evt参数,需要使用event对象
		evt = evt || event;
		console.log(evt);
	}
	/*
	我们知道在不同的浏览器上注册事件,需要采用不同的函数.
	但是直接在属性上绑定是兼容所有浏览器的,IE,FF,Chrome,都是可以的.
	疑问来了,既然这样又方便还兼顾兼容性,为什么我们还需要采用addEventListener/attachEvent.
	因为采用属性绑定事件会覆盖前一个事件,这是js的一个特性,后面加载的对象会覆盖前面加载的对象.
	*/
	//绑定事件
	btn1.onclick = function(evt){
		evt = evt || event;
		console.log("btn1 click");
	}
	//这样点击btn1之后,只会输出btn1 click,前一个绑定的onclick就被覆盖了.

	/*
	通常我们都是采用addEventListener/attachEvent来注册元素的事件,
	addEvenetListener是W3C的标准函数,attachEvent是IE遗留的函数.
	addEvenetListener(type,fn,useCapture),useCapture是设置事件触发阶段,false/true 冒泡/捕获.
	一般情况我们都采用冒泡的时候响应事件.
	attachEvent(type,fn),这个没有第三个参数,不能设置触发阶段,所以IE系列只能响应冒泡阶段.
	另外还有一个区别就是注册事件类型需要添加on前缀,W3C的标准的不用,例如click/W3C onclick/IE.
	*/
	var btn2 = document.getElementById("btn2");
	if(document.addEventListener){
		//非IE
		btn2.addEventListener("click",function(evt){
			evt = evt || event;
			console.log("btn2 click");
		},false);
	}
	else{
		//IE
		btn2.attachEvent("onclick",function(evt){
			evt = evt || event;
			console.log("btn2 click");
		});
	}

	/*
	通过属性绑定事件,并不能覆盖通过addEventListener/attachEvent注册的事件
	*/
	btn2.onclick = function(evt){
		evt = evt || event;
		console.log("btn2 click2");
	}

	/*
	由于注册事件方法需要兼容不同浏览器,所以我们又可以尝试给封装一下.
	注册事件需要随时都可能调用,类似一个工具函数,不需要保存任何状态,那么我们采用单例模式.
	*/

	/*
	简单分析一下,注册事件需要三个参数,然后通过addEventListener/attachEvent注册事件.
	*/
	function addEvent(dom,type,fn){
		if(document.attachEvent){
			//IE
			dom.attachEvent("on" + type,fn);
		}
		else{
			//非IE
			dom.addEventListener(type,fn,false);
		}
	}

	var btn3 = document.getElementById("btn3");
	//注册事件
	addEvent(btn3,"click",function(evt){
		console.log("btn3 click");
	});
	/*
	给单个dom绑定事件,这样貌似问题就不大了,但是有时候我们是需要给多个元素同时绑定事件的.
	那我们需要给dom这个参数改进一下.
	*/
	function addEvent(dom,type,fn){
		function bind(dom,type,fn){
			if(document.attachEvent){
				//IE
				dom.attachEvent("on" + type,fn);
			}
			else{
				//非IE
				dom.addEventListener(type,fn,false);
			}
		}

		//判断dom是否有多个
		if(dom.length){
			for(var i = 0,len = dom.length; i < len; i++){
				var el = dom[i];
				//判断是否是dom
				if(el && el.nodeName){
					//注册事件
					bind(el,type,fn);
				}
			}
		}
		else{
			//判断是否是dom
			if(dom && dom.nodeName){
				//注册事件
				bind(dom,type,fn);
			}
		}
	}

	//测试一下,这样我们就给全部的dom元素都绑定的click事件.
	var btns = document.getElementsByTagName("*");
	addEvent(btns,"click",function(evt){
		evt = evt || event;
		//console.log(evt.currentTarget.nodeName);
	});
	/*
	有一点需要提一下,通过addEventListener/attachEvent注册事件,是不会覆盖前一个注册事件的,
	所以注册多次就会响应多个事件函数.
	*/

	/*
	删除注册事件,也需要区分浏览器.
	w3c使用removeEventListener(type,fn,useCapture),跟注册接口对应也接收三个参数.
	ie使用detachEvent(type,fn).
	*/

	var btn4 = document.getElementById("btn4");
	btn4.onclick = function(evt){
		evt = evt || event;
		console.log("btn4 click");
	}

	//直接绑定事件,直接置成null就能删除事件.
	btn4.onclick = null;

	var btn5 = document.getElementById("btn5");
	//采用匿名函数的方式注册事件,是没办法移除的.
	addEvent(btn5,"click",function(evt){
		console.log("btn5 click");
	});
	//这样移除事件是无效的,第二个参数必须是跟注册同一个函数才行.
	if(document.detachEvent){
		//IE
		btn5.detachEvent("click",function(){});
	}
	else{
		//非IE
		btn5.removeEventListener("click",function(){},false);
	}

	function btnClick(evt){
		console.log("btn5 click2");
	}
	//再给btn5注册一个事件
	addEvent(btn5,"click",btnClick);
	//这样注册事件才可以被移除
	if(document.detachEvent){
		//IE
		btn5.detachEvent("click",btnClick);
	}
	else{
		//非IE
		//需要注意下第三个参数,如果注册的冒泡阶段,移除也需要指定为冒泡阶段,不然也是无效的.
		btn5.removeEventListener("click",btnClick,false);
	}

	/*
	发现移除事件的方法也需要区分浏览器,参数也不一样,这样的情况就有必要封装一下了.
	仿造addEvent封装一个.
	*/
	function removeEvent(dom,type,fn){
		function unbind(dom,type,fn){
			if(document.attachEvent){
				//IE
				dom.detachEvent("on" + type,fn);
			}
			else{
				//非IE
				dom.removeEventListener(type,fn,false);
			}
		}

		//判断dom是否有多个
		if(dom.length){
			for(var i = 0,len = dom.length; i < len; i++){
				var el = dom[i];
				//判断是否是dom
				if(el && el.nodeName){
					//移除事件
					unbind(el,type,fn);
				}
			}
		}
		else{
			//判断是否是dom
			if(dom && dom.nodeName){
				//移除事件
				unbind(dom,type,fn);
			}
		}
	}

	//再给btn5注册一个事件
	addEvent(btn5,"click",btnClick);
	//移除btn5注册事件,这样看起来就清爽很多了.
	removeEvent(btn5,"click",btnClick);

	/*
	事件注册和事件移除都是属于事件的操作,我们也可以把两个函数封装到一个函数中去.
	这里就不讲了,后面自定义事件封装就比较类似了.
	*/

	/*
	知识点:
	1.绑定事件的三种方式.
	2.不同绑定的方式,各有优缺.
	3.采用事件接口绑定事件,需要区分浏览器.
	4.移除事件的时候,需要注意不能移除匿名函数,还需要跟事件冒泡/捕获对应.
	*/
</script>

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics