笔记: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(); }?
?
?
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;" onmousedown="drag(this.parentNode, event);">拖动我</div><p>测试段落</p><p>测试段落</p><p>测试段落</p><p>测试段落</p></div>?
?
?
<!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 {//此处不用attacheEventtag.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代码要修改包含它们的文档,通常这样的代码必须要在文档完全加载完毕后才能运行。
?