背景
最近在做一款基于canvas的画板插件,开发过程中的画笔功能就会使用很多关于鼠标位置的属性:screenX/Y,clientX/Y,pageX/Y,offsetX/Y,以及节点offsetLeft和offsetTop。
之前在做到过类似的工具(很简单),但都是看了下鼠标位置信息的api看到那个用那个没有去深思它们之间的区别,这次在遇见坑花了点时间整理强化下自己的记忆。
要理解它们之间的差异需要正确的认识参照物。
screenX/Y
正如名字一样它的参照物是电脑的屏幕。如图所示,把浏览器缩小后拖到某个位置,绿色为鼠标点击位置,该点的screenX和Y分别为434和945,说明screen属性会受到浏览器窗口位置影响。 它表示的是当前点位在屏幕的位置。
clientX/Y
clientX/Y属性的参数物则是浏览器的可视区域。如图所示,浏览器窗口位置跟上面一直。 但黑点clientX/Y属性的值为322和800,说明client属性不会受到浏览器窗口位置的影响。它表示当前点在浏览器窗口可视区(可视区 = 浏览器窗口 – 导航栏 --工具栏 – 书签栏 – 地址栏)的位置 。
pageX/Y
pageX/Y属性的参数物也是浏览器的可视区域。但是和clientX/Y不同的是它还会加上可视区滚动的scrollX/Y。
offsetX/Y
offsetX/Y属性的参数物是设置事件的目标元素(用代码来说就是event.taeget)。举个例子,一个父元素高宽都为500px且overflow为scroll;子元素高宽都是1000px(背景为红色)。我们为子元素设置一个点击事件。如图所示:黑点的offsetX为(X1+X2) Y为(Y1+Y2);这里有一个误区容易忘记y2和x2的长度。要记住参照物为目标元素在本例中就是子元素,而子元素的实际宽高为(YA+红色区域+YB),宽度同理。
接下来是对offsetLeft的理解
要理解offsetLeft和offsetTop则需要知道offsetParent。因为offsetLeft表示当前元素左上角相对于offsetParent节点的左边界偏移的像素值。
当前元素的offsetParent是包含当前元素的定位元素(这句话我个人理解就是在祖先元素中第一个position属性值不为static的元素) 或者最近的 table,td,th,body元素。当前元素的 style.display 设置为 “none” 时/或者position设置为“fixed”时,offsetParent 返回 null。