一、鼠标事件属性
1.clientX,clientY
相对于可见视点(visual viewport)的鼠标位置,即当前浏览器显示区域(窗口)的位置,点击客户端矿口的左上角时 clientX 和 clientY 都为0,即使用户拖动了水平或垂直滚动条
document.onclick=function(e){ var event=e||window.event; console.log(event.clientX+","+ event.clientY); }
2.screenX,screenY
相对于用户屏幕的鼠标位置,一定比clientX和clientY大
document.onclick=function(e){ var event=e||window.event; console.log(event.clientX+","+ event.clientY); console.log(event.screenX+","+ event.screenY); }
3.offsetX,offsetY
相对于事件target的鼠标位置,这个属性各个浏览器的实现不一致,注意,指的是target,而不是currentTarget
4.pageX,pageY
相对于html文档的位置,>=clientX/clientY
5.layerX,layerY
相对于最近的被 positioned 的祖先元素,如果没有被 positioned 的祖先元素,就相对于html文档(类似于pageX, pageY)
二、标准化
1.计算pageX和pageY
IE8 以下不支持这两个属性。如果你使用jQuery时,它会自动为你标准化这两个属性。如果你使用的不是jQuery的标准事件,而是原生事件对象,你可以使用jQuery.event.fix
函数来标准事件对象。例如:
document.body.onclick = function(e) { e = e || window.event; e = jQuery.event.fix(e); console.log([e.pageX, e.pageY]); };
在没有jQuery的情况下,可以通过将 pageX 和 pageY 与 scrollLeft 和 scrollTop 相加来计算 clientX 和 clientY
document.body.onclick = function(e) { e = e || window.event; var pageX = e.pageX; var pageY = e.pageY; if (pageX === undefined) { pageX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; pageY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; } console.log([pageX, pageY]); };
2.计算offsetX,offsetY
根据W3C工作草案,offsetX 和 offsetY 应该相对于事件的 target 元素的内边距边缘。只用 IE 符合此标准,Webkit 相对的是边框边缘,Opera 相对的是内容边缘,而 FireFox 不支持该属性
通过 Element.getBoundingClientRect 函数,我们能够很容易的实现 Webkit 的标准-相对于边框边缘:
document.body.onclick = function(e) { e = e || window.event; var target = e.target || e.srcElement, rect = target.getBoundingClientRect(), offsetX = e.clientX - rect.left, offsetY = e.clientY - rect.top; console.log([offsetX, offsetY]); };
如果要实现W3C草案,只需要减去边框目标元素的边框大小即可:
document.body.onclick = function(e) { e = e || window.event; var target = e.target || e.srcElement, style = target.currentStyle || window.getComputedStyle(target, null), borderLeftWidth = parseInt(style[‘borderLeftWidth‘], 10), borderTopWidth = parseInt(style[‘borderTopWidth‘], 10), rect = target.getBoundingClientRect(), offsetX = e.clientX - borderLeftWidth - rect.left, offsetY = e.clientY - borderTopWidth - rect.top; console.log([offsetX, offsetY]); };