一个js闭包与冒泡事件结合的面试题
LeeSir 发表于 2015年04月03日 16:48

题目:点击页面上的任何元素时,弹出该元素的标签名。

一、循环给每一个元素添加点击事件。

function stopPropagation(e) {
	e = e || window.event;
	if(e.stopPropagation) {		//W3C阻止冒泡方法
		e.stopPropagation();
	} else {
		e.cancelBubble = true;	//IE阻止冒泡方法
	}
}
function init(){
	for(var i = 0; i< document.all.length;i++){
		(function(n){
			document.all[n].onclick = function(e){
				alert(document.all[n].nodeName);
				stopPropagation(e);
			}
		}(i));
	}
}

至于为什么用到e = e || window.event;ie中事件是全局变量window.event可以随时拿到 ,其它浏览器必须在参数中传递才能获取事件。其它浏览器中默认第一个参数传递的是事件,如果你显示的传递了别的参数,这个事件你将无法获得,所以要兼容每个浏览器,方法内首先要判断这个e参数,如果没有则是ie的判断。简单的方法是 e = e||window.event

二、事件代理。

大概说了用闭包解决该问题的思想后,面试官继续追问:如果页面元素很多,用循环控制来绑定事件性能会很差,有什么更好的办法?刚刚查了一下,需要用到事件委托。事件委托描述的是将事件绑定在容器元素上,然后通过判断点击的target子元素的类型来触发相应的事件。事件委托依赖于事件冒泡,如果事件冒泡到DOM树最高点之前被禁用的话,那以下代码就无法工作了。

function init(){
	document.all[0].onclick = function(e){
		var targetNode = e.target || e.srcElement;
		alert(targetNode.nodeName);
	};

}