在浏览器中可能发生的事件类型有很多种。在“DOM2级事件”中主要有以下几种类型的事件:
- 鼠标事件
- 键盘事件
- HTML事件
鼠标事件
鼠标事件是指与鼠标操作相关的事件。很多对象都能够响应鼠标事件,在DOM中定义了7个鼠标事件。
鼠标事件 | 描述 |
click | 用户单击鼠标左键或者按回车键时触发 |
dblclick | 用户双击鼠标左键时触发 |
mousedown | 用户按下任意鼠标键时触发 |
mouseout | 当鼠标指针离开对象所在区域时触发 |
mouseover | 当鼠标指针进入对象所在区域时触发 |
mouseup | 用户释放鼠标按钮时触发 |
mousemove | 当鼠标指针在元素内部移动时重复触发 |
页面中的所有元素都支持鼠标事件。所有的鼠标事件都会冒泡。鼠标事件也可以被取消,取消了鼠标事件不但会影响浏览器的默认行为,还会影响其它的事件。
这些鼠标事件之间存在着一些关联关系。鼠标的click
事件实际上由mousedown
和mouseup
这两个事件组成,缺一不可。dblclick
是连续的执行了两次click
事件。
在讲解鼠标事件的时候我们需要了解2个坐标信息:客户区坐标位置和屏幕坐标位置。
鼠标事件都是在浏览器视口的特定位置上发生的。这个位置信息保存在事件对象的clientX和clientY属性中。所有的浏览器都支持这两个属性,它们代表鼠标事件发生时鼠标指针在浏览器视口中的水平和垂直坐标。下图展示了浏览器视口中客户端的坐标信息。
要获取鼠标事件的客户端坐标信息,可以使用下面的代码,这里使用了DOM0级事件和DOM2级事件处理中的跨浏览器添加事件处理程序的方法。
function addEventHandler(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); }else if(element.attachEvent){ element.attachEvent("on"+type,handler); }else{ element["on" + type] = handler; } } var div = document.getElementById("myDiv"); addEventHandler(div,"click",function(event){ event = event || window.event; console.info("客户端坐标为:("+event.clientX+","+event.clientY+")"); });
查看浏览器的控制台就可以看到类似”客户端坐标为:(233,271)“的输出结果。
鼠标事件发生的时候,不仅会有相对于浏览器的坐标位置,还会有相对于电脑屏幕的位置,这个位置称为屏幕坐标位置。我们通过screenX和screenY属性就可以知道鼠标事件发生的时候鼠标指针相对于整个屏幕的坐标信息。下图展示了浏览器中鼠标事件的屏幕坐标的含义。
和获取鼠标事件的客户端坐标信息相同,使用下面的方法就可以获取浏览器中鼠标事件的屏幕坐标。
function addEventHandler(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); }else if(element.attachEvent){ element.attachEvent("on"+type,handler); }else{ element["on" + type] = handler; } } var div = document.getElementById("myDiv"); addEventHandler(div,"click",function(event){ event = event || window.event; console.info("屏幕坐标为:("+event.screenX+","+event.screenY+")"); });
鼠标事件中的键盘功能键
虽然鼠标事件通常是通过鼠标来触发的,但在按下鼠标的时候,键盘上的某些功能键的状态也可以影响到我们的操作。这些功能键是:Ctrl
、Alt
、Shift
和Meta
(Meta
在windows系统中是windows键,在Mac中是Cmd键)。
DOM为这些功能将规定了4个属性,表示这些功能键的状态。它们是:ctrlKey
、altKey
、shiftKey
和metaKey
。这些属性中包含的都是布尔值,如果相应的键被按下,那么属性的值为true
,否则值为false
。
当某个鼠标事件发生的时候,通过检查这几个属性值就可以知道用户是否同时按下了某个功能键。例如下面的例子:
function addEventHandler(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); }else if(element.attachEvent){ element.attachEvent("on"+type,handler); }else{ element["on" + type] = handler; } } var div = document.getElementById("myDiv"); addEventHandler(div,"click",function(event){ var keys = new Array(); event = event || window.event; if(event.ctrlKey){ keys.push("Ctrl"); } if(event.shiftKey){ keys.push("shift"); } if(event.altKey){ keys.push("Alt"); } if(event.metaKey){ keys.push("Meta"); } console.info("用户按下的功能键有:"+keys.join(",")); });
上面的例子在<div>
元素中点击鼠标的时候同时按下一个或多个功能键,查看控制台就可以看到你究竟是按下了哪个功能键。
鼠标事件中的相关元素
mouseover
和mouseout
事件是在鼠标指针从一个元素移动到另一个元素时发生的事件。对mouseover
而言,事件的主要目标是获得光标的元素,而相关元素是失去光标的元素。同样,对mouseout
而言,事件的主要目标是失去光标的元素,而相关元素是获得光标的元素。
DOM通过event对象的relatedTarget
属性提供相关元素的信息。这个属性只对mouseover
和mouseout
事件有值,对其它鼠标事件,该属性的值为null
。
IE不支持relatedTarget
属性,但是IE提供了不同的属性。在触发mouseover
事件的时候,IE的fromElement
属性保存了相关元素;在触发mouseout
事件的时候,IE的toElement
属性保存了相关元素。
我们可以编写一个方法来实现跨浏览器获取鼠标事件的相关元素的方法。
/* 跨浏览器获取鼠标事件的相关元素 */ function getRelatedTarget(event){ if(event.relatedTarget){ return event.relatedTarget; }else if(event.fromElement){ return event.fromElement; }else if(event.toElement){ return event.toElement; }else{ return null; } }
下面是一个具体的例子,在这个例子中,用户将鼠标从一个div
中移出,在控制台中就可以看到这次鼠标事件中鼠标移入和移出元素的信息。
function addEventHandler(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); }else if(element.attachEvent){ element.attachEvent("on"+type,handler); }else{ element["on" + type] = handler; } } function getTarget(event){ return event.target ? event.target : event.srcElement; } function getRelatedTarget(event){ if(event.relatedTarget){ return event.relatedTarget; }else if(event.fromElement){ return event.fromElement; }else if(event.toElement){ return event.toElement; }else{ return null; } } var div = document.getElementById("myDiv"); addEventHandler(div,"mouseout",function(event){ event = event || window.event; var target = getTarget(event); var relatedTarget = getRelatedTarget(event); console.info("鼠标从"+target.tagName+"移出,进入到"+relatedTarget.tagName); });
鼠标按钮
在mousedown
和mouseup
事件中,它们的event
对象保存着一个button
属性,表示按下或释放鼠标按钮。
DOM的button
属性有如下3个值:0表示主鼠标按钮,1表示鼠标中间按钮,2表示次鼠标按钮。默认情况下,主鼠标按钮是鼠标的左键,次鼠标按钮是鼠标的右键。
在IE中也提供了button
属性,这个属性和DOM的button
属性不同,它由7个值组成:
- 0表示没有按下鼠标按钮。
- 1表示按下了主鼠标按钮。
- 2表示按下了次鼠标按钮。
- 3表示同时按下了主和次鼠标按钮。
- 4表示按下了中间鼠标按钮。
- 5表示同时按下主鼠标按钮和中间鼠标按钮。
- 6表示同时按下次鼠标按钮和中间鼠标按钮。
- 7表示同时按下3个鼠标按钮。
我们可以通过下面的方法来实现跨浏览器获取button
属性。
function getButton(event){ if(document.implementation.hasFeature("MouseEvents","2.0")){ return event.button; }else{ switch(event.button){ case 0: case 1: case 3: case 5: case 7: return 0; case 2: case 4: return 2; case 6: return 1; } } }
上面的代码通过MouseEvents
特性来检测是否是DOM中的button
属性。下面是一个实际的例子,这个例子在DIV元素中按下鼠标键时,控制台中将打印出你按下的是哪一个键。
function addEventHandler(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); }else if(element.attachEvent){ element.attachEvent("on"+type,handler); }else{ element["on" + type] = handler; } } function getButton(event){ if(document.implementation.hasFeature("MouseEvents","2.0")){ return event.button; }else{ switch(event.button){ case 0: case 1: case 3: case 5: case 7: return 0; case 2: case 4: return 2; case 6: return 1; } } } var div = document.getElementById("myDiv"); addEventHandler(div,"mousedown",function(event){ event = event || window.event; var buttonKey = getButton(event); var info = ""; if(buttonKey == 0){ info = "鼠标左键被按下"; }else if(buttonKey == 1){ info = "鼠标中键被按下"; }else if(buttonKey == 2){ info = "鼠标右键被按下"; } console.info(info); });