昨天突发奇想,想做一个模拟的鼠标点击生成小球往下掉的效果。于是涉及到了js中一些鼠标点击事件,接下来我来总结顺便复习一下。
鼠标事件包括七个:

  1. mousedown 鼠标点击按下
  2. mouseup 鼠标点击抬起
  3. mouseover 鼠标悬浮
  4. mouseout 鼠标移出
  5. mouseenter 鼠标进入
  6. mouseleave 鼠标移出
  7. mousemove 鼠标移动

问题1: mouseout和mouseleave代表的都是鼠标移出事件,那么它们有什么区别呢?

接下来准备一份html文件来做个例子
HTML部分

<div class="big" onmouseout="handleMouseout()" onmouseleave="handleMouseleave()">
	<div class="sub1">子元素1</div>
	<div class="sub2">子元素2</div>
</div>

CSS部分

.big {
	width: 400px;
	height: 400px;
	background: #aaa;
}

.sub1 {
	width: 100px;
	height: 100px;
	background: #666;
}

.sub2 {
	position: relative;
	top: 50px;
	left: 50px;
	width: 100px;
	height: 100px;
	background: #666;
}

JS部分

function handleMouseout () {
	console.log("mouse out of the {big}")
}

function handleMouseleave () {
	console.log("mouse leave of the {big}")
}

image

可以看到,当鼠标从「class="big"」的元素中离开时,触发了两个事件mouseout&mouseleave,仅仅如此还不足以看出它俩的区别。那么进一步看:

image

可以看到,鼠标指针从当前元素移动到它的子元素时,仅触发了mouseout事件,并没有触发mouseleave事件,这里就可以看出它们两个的区别所在:

  • mouseout会在鼠标指针移动到本身元素可视区域之外的地方触发(子元素就属于本身元素可视区域之外的地方,可以理解为,mouseout只局限于它本身所在的zindex平面,离开该平面就会触发mouseout事件,子元素因为重叠在父元素上面,所以在z轴的维度上,它比父元素要高一个层级,所以也不属于父元素本身可视区域)
  • mouseleave只会在鼠标指针从当前元素本身移出时才会触发,不涉及zindex,可以把父元素看作一个地基,它的子元素就是建在这个地基上面的一栋栋楼房,那么如果说mouseout会在你离开该地基范围时或在该地基范围内上楼时触发,那么mouseleave就仅仅在水平离开该地基时触发。

问题2:mouseenter 和 mouseover 的关系?

答:mouseenter和mouseouver的关系就是mouseout和mouseleave的关系

对应关系: mouseenter -> mouseleave & mouseout -> mouseover

问题3:鼠标事件对象中的几对坐标值实际分别代表着什么?

取屏幕左上角为原点,右为正,下为正

1. clientX & clientY

鼠标指针基于浏览器窗口的坐标位置

2. offsetX & offsetY

鼠标指针基于事件target元素的坐标位置

3. pageX & pageY

鼠标指针基于body的坐标位置(包括被卷去的区域)

那么什么又叫做被卷去的区域
举个例子

body {
	margin: 0;
	padding: 0;
	width: 2000px;
	height: 2000px;
	background: #aaa;
}

显然我现在的笔记本电脑无法显示全整个2000px*2000px的body,并且我的页面上出现了滚动条
image
那么给body添加上如下的点击事件:

<body id="b"></body>

获取到body并且添加点击事件

document.getElementById('b').addEventListener('click', function (event) {
	console.log(`
	    clientX: ${e.clientX}
            clientY: ${e.clientY}
            screenX: ${e.screenX}
            screenY: ${e.screenY}
            offsetX: ${e.offsetX}
            offsetY: ${e.offsetY}
            pageX: ${e.pageX}
            pageY: ${e.pageY}
            x: ${e.x}
            y: ${e.y}
	`)
})

接下来看点击body的不同地方会输出什么:
首先,在页面没有滚动的情况下,点击页面最底端
image
控制台给出的数据如下:


            clientX: 303
            clientY: 850
            screenX: 303
            screenY: 954
            offsetX: 308
            offsetY: 851
            pageX: 308
            pageY: 850
            x: 303
            y: 850

可以看到,此时pageX的值为308,pageY的值为850
接下来,我把横向滚动条和纵向滚动条拉到最底端,再来点一下看看:
image
控制台返回的数据为:


	    clientX: 1047
            clientY: 830
            screenX: 1047
            screenY: 934
            offsetX: 1875
            offsetY: 1957
            pageX: 1875
            pageY: 1957
            x: 1047
            y: 830
			

这里可以看到,我把页面滚动到最底部时,点击返回的pageX为1875,pageY为1957,很显然,这两个值把滚动掉的页面的x和y也算上了,所以这就是pageX,pageY的特殊之处

4. screenX & screenY

鼠标指针基于电脑屏幕的坐标位置,不管页面如何变动,总是基于电脑屏幕

5. x & y

等价于clientXclientY

总结一下鼠标事件对象的坐标:

如果想在某一个元素内进行坐标获取操作,最好能够使用offsetXoffsetY, 但是如果只是想获取鼠标在页面上的位置,建议使用pageXpageY或者xy(也就是clientXclientY),screenXscreenY的原点是基于整个电脑屏幕的,不便于操作,一般不使用。