DOM中事件绑定补充方法


先将上一篇文章中提到的为元素增加事件的方法和移除事件的方法拿过来:

<span style="font-size:18px;">//跨浏览器添加事件
function addEvent(obj, type, fn) {
	if (obj.addEventListener) {
		obj.addEventListener(type, fn, false);
	} else if (obj.attachEvent) {
		obj.attachEvent('on' + type, fn);
	}
}

//跨浏览器移除事件
function removeEvent(obj, type, fn) {
	if (obj.removeEventListener) {
		obj.removeEventListener(type, fn, false);
	} else if (obj.detachEvent) {
		obj.detachEvent('on' + type, fn);
	}
}</span>


1、relatedTarget 属性

W3C中事件对象event提供了一个属性relatedTarget,这个属性可以再事件mouseover和mouseout中获得鼠标是从哪个元素中来和到那个元素中去。这个属性高版本的IE也支持,只不过它会弹出两个窗体,第二个窗体显示的值是null。谷歌也支持这个属性

对应的IE提供的则是 fromElement 和 toElement 分别对应事件mouseover和事件mouseout,同样是获得从那个元素中来到那个元素中去,并且属性和事件可以相互交换,但是这样式没有什么意义的。

//浏览器的兼容方法

<span style="font-size:18px;">//调用方法
addEvent(window,onload,function(){
	var box = document.getElementById("box");
	addEvent(box,"mouseover",function(evt){		//移入box对象的时候获得离box最近的那个对象
		alert(getTarget(evt).tagName);
	});
	addEvent(box,"mouseout",function(evt){		//移出box对象的时候获得离box最近的那个对象
		alert(getTarget(evt).tagName);
	})
})</span>
<span style="font-size:18px;">function getTarget(evt){
	var e = evt || window.event;
	if(e.srcElement){		//IE中获得事件源
		if(e.type == "mouseover"){		//IE8 中type描述的是事件名字符串
			return e.fromElement;
		}else if(e.type == "mouseout"){
			return e.toElement;
		}
	}else if(e.relatedTarget){		//W3C,
		return e.relatedTarget;
	}
}</span>


2、阻止默认行为

比如在某一个连接上面点击的时候,是会跳转的,我们可以再click事件中进行某些判断,判断跳转条件是否满足,如果不满足就不跳转

传统的取消默认事件是通过在需要跳转的函数后面添加一个 return false;就可以,但是这有很多弊端,第一:必须写到最后,这样导致中间的代码执行后,有可能执行不到 return false;第二:return false 写到最前那么之后的自定义操作就失效了。

而在DOM2级事件绑定中,W3C提供了一个方法用来阻止默认事件的发生:e.preventDefault();这个方法可以放在要阻止的跳转的方法中的任何一个地方,而且放在最前面还不影响后面的代码的执行,高版本的IE,谷歌都支持这个方法。阻止默认事件的代码最好是放在最前面,这样可以避免因为执行了前面的代码后就不能够执行取消默认事件的代码。

IE8同样提供了一种方法 e.returnValue = false; 效果上和W3C的preventDefault()是一样的,只是在IE11以及谷歌中已经不支持这种写法,故最好是采用W3C的方法。

//兼容代码如下

<span style="font-size:18px;">//HTML中代码
//<a href="http://www.baidu.com">百度</a>

//兼容方法
function preDef(evt){
	var e  = evt || window.event;
	if(typeof e.preventDefault == "function"){	//W3C
		//在W3C提供的这个取消默认事件前,还有一个属性,用来表示是否可以取消默认行为
		//e.cancelable
		e.preventDefault();
	}else{
		e.returnValue = false;
	}
}

//调用方法	下面会输出 a,b但是不会进行跳转
addEvent(window,"load",function(){
	var link = document.getElementsByTagName("a")[0];
	addEvent(link,"click",function(evt){
		alert("a");
		preDef(evt);	//这句话最好是放在这个匿名函数的最前面
		alert("b");
	})
})</span>



3、上下文菜单事件:contextmenu 

当我们点击右键的时候,浏览器中都会弹出windows自带的右键菜单,但是有时候我们想弹出我们自己的右键菜单,这是可以通过contextmenu事件来做到,但是前提是需要将默认的右键菜单给阻止掉,这个事件所有的浏览器兼容性都很好。

<span style="font-size:18px;">//单击页面上的某个textarea 区域显示出我们自己的右键菜单
//练习中右键菜单是一个ul组成
//HTML代码
<textarea id="txt" style="width=200px;height=200px;"></textarea>
<!--右键菜单内容,默认是隐藏的-->
<ul id="menu" style="100px;height:100px;background:yellow;display:none;position:absolute;">
	<li>百度</li>
	<li>谷歌</li>
	<li>腾讯</li>
</ul></span>
<span style="font-size:18px;">//实现方法
addEvent(window,"load",function(){
	var txt = document.getElementById("txt");
	addEvent(txt,"contextmenu",function(evt){
		preDef(evt);		//先阻止掉默认的右键菜单,方法为上面的preDef()
		
		var e = evt || window.event;
		var menu = document.getElementById("menu");
		menu.style.left = e.clientX + "px";
		menu.style.top = e.clientY + "px";
		menu.style.display = "block";		//块级元素,隐藏赋值为 none
		
		addEvent(document,"click",function(evt){
			menu.style.visibility = "hidden";		//隐藏。显示是 visible
		})
	})
})</span>


4、卸载前事件:beforeunload 

在离开某个页面的时候,会触发卸载前事件:beforeunload ,页面就会提醒是否要真的离开这个页面,但是谷歌不支持

<span style="font-size:18px;">addEvent(window,"beforeunload",function(evt){
	preDef(evt);
})</span>


5、鼠标滚轮事件:mousewheel和DOMMouseScorll

在页面中,当我们滚动鼠标中间的滚轮的时候会触发滚轮事件,mousewheel是非火狐浏览器支持的,DOMMouseScroll是火狐提供的方法,做兼容。而且,非火狐向上滚动的时候返回的是正数120,向下是-120,火狐像是是-4,向下是4

<span style="font-size:18px;">//非火狐	火狐虽然不支持这个事件,但是它也不会报错
addEvent(document,"mousewheel",function(evt){
	alert(getWD(evt));
})

//火狐
addEvent(document,"DOMMouseScroll",function(evt){
	alert(getWD(evt));
})

function getWD(evt){
	var e = evt || window.event;
	if(e.wheeldelta){		//非火狐支持
		return e.wheeldelta;
	}else if(e.detali){		//火狐支持的
		return e.detali * (-30);
	}
}</span>



原文地址:https://www.cnblogs.com/qigang/p/3841949.html