是否可以在页面加载后使用JavaScript获取鼠标位置而没有任何鼠标移动事件(不移动鼠标)?
mousemove
事件来降低浏览器的速度。
是否可以在页面加载后使用JavaScript获取鼠标位置而没有任何鼠标移动事件(不移动鼠标)?
mousemove
事件来降低浏览器的速度。
Answers:
真正的答案:不,不可能。
好的,我刚刚想到了一种方法。用覆盖整个文档的div覆盖页面。在其中,创建(例如)2,000 x 2,000个<a>
元素(以便:hover
伪类在IE 6中运行),每个元素的大小为1像素。:hover
为那些<a>
更改属性的元素创建CSS 规则(比如说font-family
)。在您的负载处理程序中,循环浏览这400万个<a>
元素中的每一个,检查currentStyle
/ getComputedStyle()
直到找到带有悬停字体的元素。从此元素外推以获取文档中的坐标。
注意:不要这样做。
<a>
覆盖给定矩形的<img>
元素(我想使用尺寸元素的绝对定位),每次缩小矩形。是的,这很荒谬,但是在第一次移动鼠标之前无法获得此信息。
编辑2020:这不再起作用。浏览器供应商似乎对此进行了修补。因为大多数浏览器都依赖于铬,所以它可能是其核心。
旧的答案:您也可以挂钩mouseenter(当mousecursor位于页面内部时,页面重新加载后会触发此事件)。扩展Corrupted的代码应该可以解决问题:
var x = null;
var y = null;
document.addEventListener('mousemove', onMouseUpdate, false);
document.addEventListener('mouseenter', onMouseUpdate, false);
function onMouseUpdate(e) {
x = e.pageX;
y = e.pageY;
console.log(x, y);
}
function getMouseX() {
return x;
}
function getMouseY() {
return y;
}
您还可以在mouseleave-event上将x和y设置为null。因此,您可以使用光标检查用户是否在页面上。
mouseleave
事件添加一个函数,该函数设置x
并y
返回null
或'undefined'
您所能做的就是为光标的x
和y
坐标创建变量,每当鼠标移动时更新它们,并按一定间隔调用一个函数以根据存储的位置执行所需的操作。
当然,这样做的不利之处在于,至少需要鼠标的一次初始移动才能使其正常工作。只要光标至少更新一次其位置,我们就能够找到其位置,而不管其是否再次移动。
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
setInterval(checkCursor, 1000);
function checkCursor(){
alert("Cursor at: " + cursorX + ", " + cursorY);
}
前面的代码每秒更新一次,并显示一条有关光标位置的消息。我希望这有帮助。
cursorX/Y
在任何事件发生之前填充这些变量的方法。
如果渲染2,000 x 2,000个<a>
元素,则@Tim Down的答案无效。
好的,我刚刚想到了一种方法。用覆盖整个文档的div覆盖页面。在其中,创建(说)2,000 x 2,000个元素(以便:hover伪类可在IE 6中运行,请参见),每个元素的大小为1像素。为那些更改属性的元素创建CSS:hover规则(比如说font-family)。在加载处理程序中,循环浏览这400万个元素中的每一个,检查currentStyle / getComputedStyle()直到找到带有悬停字体的元素。从此元素外推,以获取文档中的坐标。
注意:请勿这样做。
但是您不必一次渲染400万个元素,而是使用二进制搜索。只需使用4个<a>
元素即可:
<a>
元素getComputedStyle()
函数确定将鼠标悬停在哪个矩形中这样,考虑到屏幕宽度不超过2048像素,您最多需要重复这些步骤11次。
因此,您将生成最多11 x 4 = 44个<a>
元素。
如果您不需要确定鼠标的位置精确到一个像素,而是说10px精度就可以了。您最多将重复步骤8次,因此您需要绘制最多8 x 4 = 32个<a>
元素。
<a>
由于DOM通常很慢,因此生成和销毁元素的效果也不佳。相反,你可以只重用最初4个<a>
元素,只是调整自己top
,left
,width
和height
通过步骤你循环。
现在,创建4 <a>
也是一个过大的杀伤力。相反,在每个矩形中<a>
进行测试时,可以重复使用相同的一个元素getComputedStyle()
。因此,与其将搜索区域划分为2 x 2个<a>
元素,不如<a>
通过使用top
和left
样式属性移动元素来重用单个元素。
因此,您只需要单个<a>
元素更改其width
和height
最大11次,然后更改其top
和left
最大44次,您将拥有精确的鼠标位置。
最简单的解决方案,但并非100%准确
$(':hover').last().offset()
结果:{top: 148, left: 62.5}
结果取决于最接近的元素大小,并undefined
在用户切换选项卡时返回
undefined
无论如何它都会返回。您能详细说明如何使用吗?
undefined
当光标未悬停任何元素时(或浏览器失去焦点时),它将返回。如果您要从控制台进行测试,则可能需要设置时间间隔
setTimeout
工作。我使用的是jsfiddle,您是对的,它从未遇到过悬停事件,因为每次单击播放时它都会重绘DOM。我建议为其他人添加此提示。
我设想您可能有一个带有计时器的父页面,并且在一定时间或某个任务完成之后,您会将用户转发到新页面。现在您需要光标位置,并且由于它们正在等待,因此它们不一定要触摸鼠标。因此,使用标准事件在父页面上跟踪鼠标,然后将最后一个值通过get或post变量传递给新页面。
您可以在父页面上使用JHarding的代码,以便始终在全局变量中提供最新位置:
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
这不会帮助通过父页面以外的其他方式导航到该页面的用户。
嘲笑@SuperNova 的答案,这是一种使用ES6类的方法,该方法可以使上下文this
在回调中保持正确:
class Mouse {
constructor() {
this.x = 0;
this.y = 0;
this.callbacks = {
mouseenter: [],
mousemove: [],
};
}
get xPos() {
return this.x;
}
get yPos() {
return this.y;
}
get position() {
return `${this.x},${this.y}`;
}
addListener(type, callback) {
document.addEventListener(type, this); // Pass `this` as the second arg to keep the context correct
this.callbacks[type].push(callback);
}
// `handleEvent` is part of the browser's `EventListener` API.
// https://developer.mozilla.org/en-US/docs/Web/API/EventListener/handleEvent
handleEvent(event) {
const isMousemove = event.type === 'mousemove';
const isMouseenter = event.type === 'mouseenter';
if (isMousemove || isMouseenter) {
this.x = event.pageX;
this.y = event.pageY;
}
this.callbacks[event.type].forEach((callback) => {
callback();
});
}
}
const mouse = new Mouse();
mouse.addListener('mouseenter', () => console.log('mouseenter', mouse.position));
mouse.addListener('mousemove', () => console.log('mousemove A', mouse.position));
mouse.addListener('mousemove', () => console.log('mousemove B', mouse.position));
这是我的解决方案。它导出可以在任何地方使用的window.currentMouseX和window.currentMouseY属性。它首先使用悬停的元素(如果有)的位置,然后使用鼠标的移动来设置正确的值。
(function () {
window.currentMouseX = 0;
window.currentMouseY = 0;
// Guess the initial mouse position approximately if possible:
var hoveredElement = document.querySelectorAll(':hover');
hoveredElement = hoveredElement[hoveredElement.length - 1]; // Get the most specific hovered element
if (hoveredElement != null) {
var rect = hoveredElement.getBoundingClientRect();
// Set the values from hovered element's position
window.currentMouseX = window.scrollX + rect.x;
window.currentMouseY = window.scrollY + rect.y;
}
// Listen for mouse movements to set the correct values
document.addEventListener('mousemove', function (e) {
window.currentMouseX = e.pageX;
window.currentMouseY = e.pageY;
});
}())
Composr CMS来源: https : //github.com/ocproducts/composr/commit/a851c19f925be20bc16bfe016be42924989f262e#diff-b162dc9c35a97618a96748639ff41251R1202
var x = 0;
var y = 0;
document.addEventListener('mousemove', onMouseMove, false)
function onMouseMove(e){
x = e.clientX;
y = e.clientY;
}
function getMouseX() {
return x;
}
function getMouseY() {
return y;
}
我想我可能有一个合理的解决方案,而无需计算div和pixel..lol
只需使用动画帧或函数的时间间隔即可。尽管只是启动一次,您仍然需要一次鼠标事件,但是从技术上讲,您可以将其定位在任意位置。
本质上,我们始终在没有鼠标移动的情况下跟踪虚拟div。
// create a div(#mydiv) 1px by 1px set opacity to 0 & position:absolute;
下面是逻辑。
var x,y;
$('body').mousemove(function( e ) {
var x = e.clientX - (window.innerWidth / 2);
var y = e.clientY - (window.innerHeight / 2);
}
function looping (){
/* track my div position 60 x 60 seconds!
with out the mouse after initiation you can still track the dummy div.x & y
mouse doesn't need to move.*/
$('#mydiv').x = x; // css transform x and y to follow
$('#mydiv)'.y = y;
console.log(#mydiv.x etc)
requestAnimationFrame( looping , frame speed here);
}