笔记:JS权威指南17章—事件和事件属性

目前使用的3中完全不同的不兼容的事件处理模型:
1.原始事件模型:通常非正式把它看作0级DOM API的一部分内容。尽管它的特性有限,但所有启用Javascript的浏览器都支持它,因此具有可移植性。
2.标准事件模型:2级DOM标准对它进行了标准化,除IE外的所有浏览器都支持他。
3.Internet Explorer事件模型:最初由IE4引入。具有标准事件模型的许多高级特性,但不具有全部特性。

把一个元素设置为多个文档元素的事件句柄:

//在链接前请求用户的确认
function confirmLink() {
	return confirm("您确认要访问“ + this.href + ” 吗?");
}
function confirmAllLinks() {
	for(var i = 0; i < document.links.length; i++) {
		document.links[i].onclick = confirmLink;
	}
}



假定对象o,具有mymethod方法,可以用下面代码注册一个事件句柄

button.onclick = o.mymethod


这个语句使button.onclick引用与o.mymethod相同的函数。现在这个函数既是o的方法,也是button的方法。当浏览器触发这个事件句柄时,它将把该函数作为button对象的方法调用,而不是作为o对象的方法调用。关键字this引用Button对象,而不是引用对象o。不要认为可以让浏览器把一个事件句柄作为其他对象的方法调用。如果想这样做,必须直接调用

button.onclick = function() { o.mymethod(); }

 

 

 

列表显示了所有事件模块、以及它定义的事件接口和它支持的事件类型。

模块名

事件接口

事件类型

HTMLEvents

Event

abortblurchangeerrofocusloadresrtresizescrollselectsubmitunload

MouseEvents

MouseEvents

clickmousedownmousemovemouseovermouseup

UIEvents

UIEvent

DOMActivateDOMFocuslnDOMFocusOut

EventHTMLEvent 模块定义的事件类型使用 Event 接口。其他事件类型都使用该接口,即所有事件对象都实现了 Event 接口,并提供了适用于所有事件类型的详细信息。 Event 接口定义了如下属性:

type

发生事件的类型。该属性的值是事件类型名(如: ’click’’mouseover’

target

发生事件的节点,可能与 currentTarget 不同

currentTarget

当前正在运行事件句柄的节点。如果在传播过程的捕捉阶段或起泡阶段处理事件,这个属性的值就与 target 属性的值不同。

eventPhase

一个数字,指定当前所处的事件传播过程的阶段。它的值为常量: Event.CAPTURE_PHASE, Event_AT_TARGET, Event.BUBBLING_PHASE

timestamp

一个 Date 对象,声明事件何时发生

bubble

布尔值,声明该事件是否在文档树中起泡

cancelabel

布尔值,声明该事件是否具有能用 preventDefault() 方法取消的默认动作

Event 接口还定义了 stopPropagation()preventDefault() 方法,所有事件对象都实现了它们。调用 stopPropagation() 方法可以阻止事件从当前正在处理它的节点传播。调用 preventDefault() 方法阻止浏览器执行与该事件默认的相关动作。

 

UIEventUIEvent 接口是 Event 的子接口(拥有 Event 接口定义的属性)、是 MouseEvent 接口的父接口。

view 属性:发生时间的 Window 对象

detail 属性:对于 click 事件、 mousedown 事件和 mouseup 事件,这个字段代表点击的次数, 1 代表点击一次、 2 代表双击、 3 代表点击三次。对于 DOMActivate 事件,这个字段的值为 1 ,表示正常激活, 2 表示超级激活(如双击鼠标或同时按下 shiftenter

 

MouseEvent :继承 Event 接口和 UIEvent 接口的所有属性和方法,此外还定义了如下属性

button

声明在 mousedownmouseupclick 事件中,哪个鼠标键改变了状态。 0 表示左键, 1 表示中间键, 2 表示右键。

altKey,ctrlKey,metaKey,shiftKey

4 个布尔值声明在鼠标事件发生时,是否按住了 alt 键, ctrlshiftmeta

clientX,clientY

声明鼠标指针相对于客户区或浏览器窗口的 X 坐标和 Y 坐标。这 2 个属性不考虑滚动,如果事件发生在窗口的顶部,无论文档滚动了多元, clientY 都是 0

screenX, screenY

声明鼠标指针相对于用户显示器的左上角的 X 坐标和 Y 坐标

relatedTarget

对于 mouseover 事件,它是鼠标移到目标上是所离开的那个节点

对于 mouseout 事件,它是离开目标时,鼠标进入的节点

 

 



在0级DOM事件模型中。浏览器把事件分派给发生事件的文档元素。如果那个对象具有合适的事件句柄。就运行这个句柄。除此之外,不再执行其他的操作。
在2级DOM中,当事件发生在文档元素上时,目标的事件句柄就被触发。此外,目标的每个祖先元素也有机会处理那个事件。

事件捕获分三个阶段进行:
1.在捕捉(caputuring)阶段,事件从Document对象沿着文档树向下传播给目标节点。如果目标的任何一个祖先专门注册了捕捉事件句柄,那么在事件传播的过程中,就会运行这些句柄。
2.直接注册在目标上的适合的事件句柄将运行。
3.起泡(bubbling)阶段:事件将从目标元素向上传播回或起泡回Document对象的文档层次。(虽然所有事件都受时间传播的捕捉阶段的支配,但并非所有类型的事件都起泡)

在2级事件模型中,可调用对象的addEventListener()方法为特定元素注册事件句柄
document.myform.addEventListener("submit", function(e) { alert(e);}, false);
addEventListener函数对应的是removeEventListener

IE事件句柄的注册:attachEvent()方法和detachEvent()

function highlight() { /* code goes here*/}
document.getElementById('myelt').attachEvent("onmouseover", highlight);


attachEvent()和addEventListener()方法相似,除以下几点外:
1.只是由于IE事件不支持事件捕捉。因此attachEvent()方法只有2个参数
2.传递给IE方法的事件句柄名字应该包含一个“on”前缀
3.用attachEvent()注册的函数将被作为全局函数调用,即在attachEvent()注册的事件句柄执行时,关键字this引用的是Window对象,而不是事件的目标元素
4.attachEvent()允许同一个事件句柄注册多次。

IE中的事件起泡:IE事件模型中没有2级DOM模型具有的事件捕捉的概念。但在IE模型中,事件可以沿着包容层次向上起泡。在2级模型中,事件起泡只适用于原始事件或输入事件(主要是鼠标和键盘事件),不适用于高级的语义事件。IE中的事件起泡和2级DOM事件模型中的事件起泡之间的差别在于停止起泡的方式。IE Event对象没有DOM Event对象具有的stopPropagation()方法,所以要阻止事件起泡或制止它在包含层次中进一步传播,IE事件句柄必须把Event对象的cancelBubble属性设置为true:

window.event.cancelBubble = true;



设置cancelBubble属性只使用于当前事件。当新事件生成时,将赋予window.event新的Event对象,cancelBubble属性还将还原为它的默认值false

 

下面代码为拖动决定定位的元素:

<script type="text/javascript">
//拖动绝对定位的元素
function drag(elementToDrag, event) {
	var startX = event.clientX, startY = event.clientY;
	var origX = elementToDrag.offsetLeft, origY = elementToDrag.offsetTop;
	var deltaX = startX - origX, deltaY = startY - origY;
	
	if (document.addEventListener) {
		document.addEventListener("mouseover", moveHandler, true);
		document.addEventListener("mouseup", upHandler, true);		
	}
	else if (document.attachEvent) {
		//IE5+事件模型
		elementToDrag.setCapture();
		elementToDrag.attachEvent("onmousemove", moveHandler);
		elementToDrag.attachEvent("onmouseup", upHandler);
		elementToDarg.attachEvent("onlosecapture", upHandler);		
	}
	else {
		//IE4事件模型
		var oldmovehandler = document.onmousemove;
		var olduphandler = document.onmouseup;
		document.onmousemove = moveHandler;
		document.onmouseup = upHandler;	
	}
	
	if (event.stopPropagation) event.stopPropagation();
	else event.cancelBubble = true;	
	
	//阻止默认动作
	if (event.preventDefault) event.preventDefault();
	else event.returnValue = false;
	
	function moveHandler(e) {
		if (!e) e = window.event;	
		elementToDrag.style.left = (e.clientX - deltaX) + "px";		
		elementToDrag.style.top = (e.clientY - deltaY) + "px";
		
		if (e.stopPropagation) e.stopPropagation();
		else e.cancelBubble = true;
	}
	
	function upHandler(e) {
		if (!e) e = window.event;
		
		if (document.removeEventListener) {
			//DOM事件模型
			document.removeEventListener('mouseup', upHandler, true);
			document.removeEventListener("mousemove", moveHandler, true);
		}
		else if (document.detachEvent) {
			//IE5+事件模型
			elementToDrag.detachEvent("onlosecapture", upHandler);
			elementToDrag.detachEvent("onmouseup", upHandler);
			elementToDrag.detachEvent("onmousemove", moveHandler);
			elementToDrag.releaseCapture();
		}
		else {
			//IE4事件模型
			document.onmouseup = oldhandler;
			document.onmousemove = oldmoveHandler;
		}
		
		if (e.stopPropagation) e.stopPropagation();
		else e.cancelBubble = true;
	}
}
</script>
</head>
<body>
<div style="position:absolute; left:100px; top:100px; width:250px; background-color:white; border:solid black;">
<div style="background-color:gray; border-bottom:dotted black; padding:3px; font-family:sans-serif; font-weight:bold;" οnmοusedοwn="drag(this.parentNode, event);">
拖动我</div>
<p>测试段落</p><p>测试段落</p><p>测试段落</p><p>测试段落</p>
</div>

 

 

 

按键事件:如果 alt,ctrl,shift 和一个按键一起按下,这通过事件对象的 altKey,ctrlKey,shiftKey 属性来表示。

Firefox 中定义了两个属性, keyCode 存储了一个按键的较低层次的虚拟键盘码,并且和 keydown 事件一起发送; charCode 存储了按下一个键时所产生的可打印的字符的编码,并且和 keypress 事件一起发送(功能按键产生一个 keypress 事件,此时 charCode0keyCode 包含了虚拟按键码)。

IE 中,只有一个 keyCode 属性,并且它的解释也取决于事件的类型,对于 keydown 事件来说, keyCode 是一个虚拟按键码;对于 keypress 事件来说, keyCode 是一个字符码。字符码可以使用 String.fromCharCode() 转换为字符。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>限制用户输入某一组字符</title>
</head>
<body>
邮编:<input type="text" id="zip" allowed="0123456789" messageid="zipwarn">
<span id="zipwarn" style="color:red; visibility:hidden">只能输入数字<span>
</body>
<script type="text/javascript">
(function check() {
	//文档加在完毕后,执行init函数
	if (window.addEventListener) window.addEventListener('load', init, false);
	else if(window.attachEvent) window.attachEvent("onload", init);
	
	
	//查找input元素,并在其上注册init函数
	function init() {
		var inputtags = document.getElementsByTagName("input");		
		for(var i = 0; i < inputtags.length; i++) {
			var tag = inputtags[i];
			if (tag.type != "text") continue;//仅需要text框			
			var allowed = tag.getAttribute("allowed");
			if (!allowed) continue;//有allowed属性
			
			if (tag.addEventListener) 			
				tag.addEventListener("keypress", filter, false);
			else {
				//此处不用attacheEvent
				tag.onkeypress = filter;
			}		
		}	
	}
	
	//处理用户输入
	function filter(event) {
		//获取事件模型和字符码
		var e = event || window.event;
		var code = e.charCode || e.keyCode;
		
		if (e.charCode == 0) return true;
		if (e.ctrlKey || e.altKey) return true;
		if (code < 32) return true;
		
		var allowed = this.getAttribute("allowed");
		var messageElement = null;
		var messageid = this.getAttribute("messageid");		
		if (messageid)
			messageElement = document.getElementById(messageid);
			
		var c = String.fromCharCode(code);
		
		if (allowed.indexOf(c) != -1) {
			if (messageElement) messageElement.style.visibility = 'hidden';
			return true;		
		}
		else {
			if (messageElement) messageElement.style.visibility = "visible";
			if (e.preventDefault) e.preventDefault();
			if (e.returnValue) e.returnValue = false;
			return false;		
		}	
	}
})();

</script>
</html>
 


鼠标事件:当一个鼠标事件发生的时候,事件对象的clientX和clientY属性保存了鼠标指针的位置。

onload事件:有些javascript代码要修改包含它们的文档,通常这样的代码必须要在文档完全加载完毕后才能运行。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值