DOM2级事件对象的继承关系如下图所示:
下面看一看Event和MouseEvent对象的属性,并介绍通过这些属性可以获得哪些信息。
1. DOM2事件规范中的Event对象
事件对象中包含着用于控制事件流和目标对象的方法和属性。包括:
□ bubbles:布尔值,表示是否是冒泡阶段
□ cancelable:布尔值,表示事件是否具有可以取消的默认动作
□ currentTarget:当前正在处理的DOM元素
□ target:最早调用事件序列的对象(EventTarget对象的实例)
□ timestamp:DOMTimeStamp对象,用来确定创建事件后的毫秒数
□ type:包含事件名称(例如click)的字符串
□ eventPhase:表示处于事件流的阶段,使用1-3的整数来表示,也可以使用Event常量CAPTURE_PHASE、AT_TARGET和BUBBLING_PHASE。如下所示:
function eventListener(W3CEvent) { switch(W3CEvent.eventPhase) { case Event.CAPTURING_PHASE: //code to run if in the capturing phase break; case Event.AT_TARGET: //code to run if this is the target break; case Event.BUBBLING_PHASE: //code to run if in the bubbling phase break; } }
还可以根据事件的阶段使用target或currentTarget属性:
function eventListener(W3CEvent) { window.open(W3CEvent.currentTarget.href); W3CEvent.preventDefault(); } var anchor = document.getElementById('example'); anchor.addEventListener('click',eventListener,false);
W3C也定义了下列Event对象的方法:
□ initEvent(eventType,canBubble,cancelable):初始化通过document.createEvent(‘Event’)方法创建的事件对象
□ preventDefalt():取消对象的默认动作
□ stopPropagation():停止事件流的进一步执行
2. DOM2事件规范定义的MouseEvent对象
对于所有的W3C DOM鼠标事件而言,传递到事件侦听器中的事件对象都是MouseEvent对象的实例。MouseEvent对象的属性如下:
□ altKey、ctrlKey和shiftKey:布尔值,表示是否按住Alt、Ctrl或Shift键
□ button:表示鼠标键的整数值。0表示鼠标左键,1表示鼠标中键(如果有),2表示鼠标右键。例如:
if(W3CEvent.button==0) { // 单击左键的代码 }
或者使用常量:
if(W3CEvent.button==MouseEvent.BUTTON_LEFT) { // 单击左键的代码 }
□ clientX和clientY:表示事件发生位置相对于浏览器窗口的水平和垂直坐标。例如:
document.addEventListener('click',function(W3CEvent) { alert('client: (' + W3CEvent.clientX + ',' + W3CEvent.clientY + ')'); },false);
下图展示了滚动网页前后clientX和clientY表示的位置:
□ screenX和screenY:表示事件发生位置相对于屏幕的水平和垂直坐标。下图展示了screenX和screenY表示的位置:
□ relatedTarget:引用与事件相关的“次要目标”。在多数情况下,这个属性值是null,但在mouseover事件中,它引用的是鼠标离开的前一个对象;同样,在mouseout事件中,它引用的是鼠标之前进入的那个对象。
3. 处理诸多浏览器不兼容问题
访问事件的目标元素:IE没有提供target和currentTarget属性,但却提供了srcElement属性。对于Safari而言,文本节点会代替包含它的元素节点变成事件的目标对象。要解决这些问题,添加自定义的ADS.getTarget()方法:
/** * 访问事件的目标元素 */ function getTarget(eventObject) { eventObject = eventObject || getEventObject(eventObject); // 如果是W3C或MSIE模型 var target = eventObject.target || eventObject.scrElement; // 如果是Safari,则将目标对象指定为文本节点的父元素 if(target.nodeType == ADS.node.TEXT_NODE) { target = node.parentNode; } return target; } window['ADS']['getTarget'] = getTarget;
通过这个方法可以取得给定事件的目标:
ADS.addEvent(window, 'load', function() { function eventListener(W3CEvent) { //取得目标 var target = ADS.getTarget(W3CEvent); window.open(target.href); } var anchor = document.getElementById('example'); addEvent(anchor, 'click', eventListener); });
确定单击了鼠标哪个键:W3C规定:
□ 0表示按下了左键
□ 1表示按下了中键
□ 2表示按下了右键
Microsoft的规定如下:
□ 0表示没有按下任何键
□ 1表示按下左键
□ 2表示按下右键
□ 3表示同时按下了左右键
□ 4表示按下了中键
□ 5表示同时按下了左中键
□ 6表示同时按下了右中键
□ 7表示同时按下了所有三个键
解决这个不兼容问题的方法是:检测事件具有toString()方法并且返回的是MouseEvent,那么考虑使用W3C的方式;否则如果仍然存在button属性,那就可以假设是IE了。现在添加自定义的ADS.getMouseButton()方法:
/** * 确定按下了鼠标哪个键 */ function getMouseButton(eventObject) { eventObject = eventObject || getEventObject(eventObject); // 初始化一个对象变量 var buttons = { 'left':false, 'middle':false, 'right':false }; // 检查eventObject对象的toString()方法的值 // W3C DOM对象有toString方法而且返回值为MouseEvent if(eventObject.toString && eventObject.toString().indexOf('MouseEvent') != -1) { // W3C方法 switch(eventObject.button) { case 0: buttons.left = true; break; case 1: buttons.middle = true; break; case 2: buttons.right = true; break; default: break; } } else if(eventObject.button) { // MSIE方法 switch(eventObject.button) { case 1: buttons.left = true; break; case 2: buttons.right = true; break; case 3: buttons.left = true; buttons.right = true; break; case 4: buttons.middle = true; break; case 5: buttons.left = true; buttons.middle = true; break; case 6: buttons.middle = true; buttons.right = true; break; case 7: buttons.left = true; buttons.middle = true; buttons.right = true; break; default: break; } } else { return false; } return buttons; } window['ADS']['getMouseButton'] = getMouseButton;
处理鼠标的位置:虽然W3C和IE都定义了clientX和clientY鼠标,但它们在确定滚动后的位移属性时却不相同。W3C使用document.documentElement.scrollTop,而IE则使用document.body.scrollTop。对于Safari而言,它把位置信息放在了事件的pageX和pageY属性中。下面的ADS.getPointerPositionInDocument()方法一并处理了这些情况:
/** * 取得鼠标指针在文档中的位置 */ function getPointerPositionInDocument(eventObject) { eventObject = eventObject || getEventObject(eventObject); var x = eventObject.pageX || (eventObject.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)); var y= eventObject.pageY || (eventObject.clientY + (document.documentElement.scrollTop || document.body.scrollTop)); //相对于文档原点的坐标 return {'x':x,'y':y}; } window['ADS']['getPointerPositionInDocument'] = getPointerPositionInDocument;
有了ADS.getPointerPositionInDocument()方法,就可以通过mousemove事件让一个元素跟随鼠标指针移动:
ADS.addEvent(window,'load',function() { // 取得要移动的对象 var object = document.getElementById('follow'); // 绝对定位 object.style.position = 'absolute'; // 事件侦听器 function eventListener(W3CEvent) { var pointer = ADS.getPointerPositionInDocument(W3CEvent); // 相对于鼠标指针来定位对象 object.style.left = pointer.x + 'px'; object.style.top = pointer.y + 'px'; } // 在document上注册事件侦听器 ADS.addEvent(document,'mousemove',eventListener); });
4. 访问键盘命令
可以通过事件对象的keyCode属性取得按键的Unicode值。添加到ADS库中的ADS.getKeyPressed()方法,可以通过它取得按键代码及相关的ASCII值:
/** * 从事件对象中取得按键值 */ function getKeyPressed(eventObject) { eventObject = eventObject || getEventObject(eventObject); var code = eventObject.keyCode; var value = String.fromCharCode(code); return {'code':code,'value':value}; } window['ADS']['getKeyPressed'] = getKeyPressed;
通过这个方法就可以确定在键盘事件中按下的键了。例如:
ADS.addEvent(document, 'keydown', function(W3CEvent) { var key = ADS.getKeyPressed(W3CEvent); ADS.log.write(key.code + ':' + key.value); });
转载请注明:陈童的博客 » ADS4.5 响应用户操作和事件——跨浏览器的事件属性和方法