Mouseenter和mouseover的区别
这两个都是鼠标移入元素内部时触发,它们的区别是mouseenter事件没有冒泡阶段,而mouseover事件则有冒泡阶段,这是第一个区别。
第二个区别是触发的几率不一样:
- 鼠标从元素外进入元素内,一定会触发mouseenter,但不一定触发mouseover。因为mouseover只有当元素有空间被鼠标直接接触到才能触发。即使同时触发,它们的先后顺序在不同的浏览器也有差别:在Chrome42中,mouseenter事件比mouseover事件先派发;在IE5.5-10,Firefox37中,mouseover事件比mouseenter事件先触发。
- 鼠标从子元素移入当前元素,不会触发mouseenter,但有可能会触发mouseover(前提是当前元素有空间可以被鼠标直接接触到)。
有一点需要注意的是,理论上父元素的mouseenter应该比子元素的mouseenter先触发,但在Chrome42中则不一定是这样。当父元素没有空间可以被鼠标直接接触到的时候,鼠标直接移入子元素中,首先触发的是子元素的mousenter,然后才是父元素的mouseenter。
Mouseleave和mouseout的区别
这两个都是鼠标移出元素时触发,它们的区别是mouseleave事件没有冒泡阶段,而mouseout事件则有冒泡阶段,这是第一个区别。
第二个区别是触发的几率不一样:
- 鼠标从元素内移到元素外,两个事件都只触发一次,但它们的先后顺序在不同的浏览器有差别:在Chrome42中,mouseleave事件比mouseout事件先派发;在IE5.5-10,Firefox37中,mouseout事件比mouseleave事件先触发。
- 鼠标从元素进入子元素,不会触发mouseleave,但会触发mouseout。
Mousedown、mouseup、mousemove
这三个事件都有冒泡阶段,这是它们唯一的共同点。
鼠标在元素上点击(左键、右键,包括中间滚轴点击)的时候就会触发mousedown事件,在拖拽元素的操作中,通常是在这个事件的监听器中记录鼠标点下时的鼠标位置。
Mouseup是鼠标按键松开时,鼠标所在位置直接接触的元素触发的事件。因此,mousedown和mouseup可能不是在同一个元素上触发。
Click、contextmenu与dblclick
在IE5-10和Chrome中,Click仅指鼠标左键和滚轴点击,鼠标右键点击触发的是contextmenu事件。
而在Firefox37,鼠标右键点击同时会触发click事件,而且click事件在contextmenu事件之前触发。
而dblclick是连续两次快速单击鼠标左键触发的事件,常见问题也出在这,因为dblclick同时会触发两次click事件。目前没有完美的方法解决这个问题,所以一般不用dblclick。
Click事件同时包含会触发mousedown和mouseup这两个事件,只有当这两个事件发生在同一个元素上时才会触发click事件。因此其先后顺序是mousedown、mouseup、click。
Mousewheel
这个事件应该说是兼容性最差的鼠标事件,因为Firefox完全不支持。IE6+和Chrome都支持这个事件。
虽然Firefox不支持,但滚轴转动一般也是滚动条在动,因此监听元素的scroll事件即可,所以这个事件一般在应用中很少用,手持设备更没有这个事件。不排除这个事件在将来被淘汰,所以尽量不用。
Window & document上的鼠标事件
IE6-8,window不会派发或接收以上任何鼠标事件,但document可以接收mouseover、mouseout、mousedown、mouseup和mousemove事件。Firefox37,Chrome42和IE9+,在window和document上都可以接受mouseover、mouseout、mousedown、mouseup和mousemove事件。
Chrome42支持document对象触发mouseenter和mouseleave事件,window对象不能触发mouseenter和mouseleave事件。
IE6-10和Firefox37不支持document和window触发mouseenter和mouseleave事件。
Body支持触发mouseenter和mouseleave事件,但如果需要监测鼠标是不是在当前窗口,不能完全依靠监听body上的这两个事件来判断。因为body也是有高度的,不一定能撑满整个窗口。兼容性最好的方法是监听document的mouseover和mouseout事件。
需要额外注意的是,在IE和Chrome中,鼠标即使在元素上没有移动,每隔一小段时间仍然会触发mousemove事件,而Firefox则不会。
鼠标位置
屏幕坐标 – event.screenX, event.screenY
screenX和screenY带表的是鼠标在整个屏幕上的坐标。
窗口坐标-event.clientX, event.clientY
这个鼠标在浏览器客户窗口区域(实际展示页面的那部分)的坐标。客户窗口区域不包括浏览器内部出现的滚动条和其他窗口附件(比如firebug)。
不管是横坐标还是纵坐标,鼠标客户坐标一般都比屏幕坐标要小,因为浏览器最外层一般是有框的。
在支持position:fixed的浏览器中,这两个属性是非常有用的,尤其是clientY对应的就是fixed定位的y坐标。
元素坐标-event.offsetX,event.offsetY
当鼠标事件发生在某个元素上时,这个坐标就是鼠标相对于元素最左上角的一个坐标,最大坐标值取决于元素的大小。也就是说这个坐标是元素内部坐标系的一个新坐标,只跟元素大小有关,原点位于元素最左上角。
IE5-10和Chrome都支持着两个属性,但在Firefox是没有这两个属性的。
这两个属性在拖拽元素的时候比较有用,利用这两个值可以保证鼠标在拖的过程中一直位于初始点击元素的位置。但因为Firefox不支持着两个属性,导致这个计算有些复杂。好在从Firefox3开始元素就支持getBoundingClientRect()方法,通过这个方法可以获取元素相对于浏览器窗口的坐标。然后使用鼠标事件的窗口坐标减去元素的窗口坐标就是相对元素左上角的偏移坐标,也就是offsetX和offsetY了。
移动偏移向量-event.movementX,event.movementY
这两个值是两个鼠标移动事件间隔时间中当中鼠标移动的相对坐标,计算方式是:currentEvent.movementX =currentEvent.screenX - previousEvent.screenX
。
目前只有Firefox,Chrome支持这两个属性。