如何获得没有事件的鼠标位置(不移动鼠标)?

是否有可能获得鼠标位置与JavaScript页面加载后,没有任何鼠标移动事件(不移动鼠标)?

280426 次浏览

真实的答案:不,这是不可能的。

好的,我刚想到一个办法。用覆盖整个文档的div覆盖您的页面。在其中,创建(比如说)2,000 x 2,000个<a>元素(这样:hover伪类才能在IE 6中工作,参见),每个元素的大小为1像素。为那些改变属性(比如font-family)的<a>元素创建一个CSS :hover规则。在加载处理程序中,循环遍历400万个<a>元素,检查currentStyle / getComputedStyle(),直到找到带有悬浮字体的元素。从这个元素向后推断得到文档中的坐标。

注意:不要这样做

你能做的就是为你的光标的xy坐标创建变量,每当鼠标移动时更新它们,并在一段时间间隔内调用一个函数来对存储的位置做你需要做的事情。

当然,这样做的缺点是,至少需要一次初始鼠标移动才能使其工作。只要游标至少更新一次位置,无论它是否再次移动,我们都能够找到它的位置。

var cursor_x = -1;
var cursor_y = -1;
document.onmousemove = function(event)
{
cursor_x = event.pageX;
cursor_y = event.pageY;
}
setInterval(check_cursor, 1000);
function check_cursor(){console.log('Cursor at: '+cursor_x+', '+cursor_y);}

上面的代码每秒更新一次,并显示光标所在的位置。我希望这能有所帮助。

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;
}

我设想,也许您有一个带有计时器的父页面,在一定时间或任务完成后,您将用户转发到一个新页面。现在你想要光标的位置,因为它们在等待,所以它们不一定会碰到鼠标。因此,使用标准事件跟踪父页面上的鼠标,并通过get或post变量将最后一个值传递给新页面。

你可以在你的父页上使用JHarding的代码,这样最新的位置总是在全局变量中可用:

var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}

这将无法帮助通过父页面以外的方式导航到此页面的用户。

我实现了一个水平/垂直搜索,(首先让一个div充满垂直排列的竖线链接,然后让一个div充满水平排列的竖线链接,然后简单地看看哪个有悬停状态),就像Tim Down上面的想法,它工作得相当快。遗憾的是,不工作在Chrome 32上的KDE。

jsfiddle.net/5XzeE/4/

编辑2020:这是工作了。看起来是这样,浏览器供应商修补了这个问题。因为大多数浏览器都依赖于chromium,所以它可能位于浏览器的核心。

< p >老回答: 您还可以钩子mouseenter(当mousecursor在页面内时,该事件在页面重新加载后触发)。扩展损坏的代码应该做到这一点:

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为空。你可以用光标检查用户是否在你的页面上。

你可以尝试一些类似Tim Down建议的东西——但不是为屏幕上的每个像素设置元素,而是只创建2-4个元素(框),并动态更改它们的位置、宽度和高度,递归地将屏幕上可能的位置除以2-4,从而快速找到鼠标的真实位置。

例如,第一个元素占据屏幕的左右半部分,然后是上下半部分。到目前为止,我们已经知道鼠标位于屏幕的哪四分之一,能够重复—发现这个空间的哪四分之一……

如果你渲染2000 x 2000个<a>元素,@Tim Down的答案是无效的:

好吧,我刚想到一个办法。覆盖您的页面与div 覆盖整个文档。在其中,创建(比如说)2,000 x 2,000 元素(这样:hover伪类才能在IE 6中工作,见), 每1像素大小。为这些元素创建CSS:hover规则 这将改变一个属性(比如font-family)。在你的负载处理程序中, 循环检查400万个元素中的每一个 currentStyle / getComputedStyle(),直到找到带有 悬停字体。从这个元素向后推断得到坐标

N.b.,别这样。

但是你不需要一次呈现400万个元素,而是使用二分搜索。只需使用4个<a>元素即可:

  • 第一步:考虑整个屏幕作为开始搜索区域
  • 步骤2:将搜索区域分割为2 × 2 = 4个矩形<a>元素
  • 步骤3:使用getComputedStyle()函数确定鼠标悬停在哪个矩形中
  • 步骤4:将搜索区域缩小到该矩形,并重复步骤2。

这样你将需要重复这些步骤最多11次,考虑到你的屏幕不超过2048px。

所以你将生成最多11 x 4 = 44 <a>元素。

如果你不需要确定鼠标位置精确到一个像素,但说10px的精度是可以的。你将重复这些步骤最多8次,所以你将需要绘制最多8 x 4 = 32 <a>元素。

生成并销毁<a>元素也不能执行,因为DOM通常很慢。相反,你可以重用最初的4个<a>元素,并在循环步骤时调整它们的topleftwidthheight

现在,创建4 <a>也是多余的。相反,当测试每个矩形中的getComputedStyle()时,可以重用相同的<a>元素。因此,不需要将搜索区域分割为2 × 2个<a>元素,只需通过使用topleft样式属性移动单个<a>元素即可。

所以,你所需要的只是一个<a>元素改变它的widthheight max 11次,改变它的topleft max 44次,你就会得到准确的鼠标位置。

你不必移动鼠标来获取光标的位置。该位置也会在mousemove以外的事件中报告。下面是一个单击事件的例子:

document.body.addEventListener('click',function(e)
{
console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});

最简单的解决方案,但不是100%准确

$(':hover').last().offset()
< p >结果:{top: 148, left: 62.5}
结果取决于最近的元素大小,并在用户切换选项卡时返回undefined

重复@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.currentMouseXwindow.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
window.addEventListener('mousemove', function (e) {
window.currentMouseX = e.pageX;
window.currentMouseY = e.pageY;
}, /*useCapture=*/true);
}())

< a href = " https://compo。sr" rel="noreferrer">合成CMS来源: https://github.com/ocproducts/composr/commit/a851c19f925be20bc16bfe016be42924989f262e#diff-b162dc9c35a97618a96748639ff41251R1202

我想我可能有一个合理的解决方案,不用计算div和像素..哈哈

简单地使用动画帧或一个时间间隔的函数。你仍然需要一个鼠标事件一次,虽然只是启动,但技术上你可以把它放在任何你喜欢的地方。

从本质上讲,我们一直在跟踪一个虚拟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);
}

不是鼠标位置,但是,如果你正在寻找当前光标位置(用于获取最后键入的字符等用例),那么,下面的代码片段工作正常。
这将给你与文本内容相关的游标索引

window.getSelection().getRangeAt(0).startOffset

是的,这是可能的。

如果你添加“mouseover”;事件,它会立即触发,你可以得到鼠标的位置,当然,如果鼠标指针在文档上。

   document.addEventListener('mouseover', setInitialMousePos, false);


function setInitialMousePos( event ) {
console.log( event.clientX, event.clientY);
document.removeEventListener('mouseover', setInitialMousePos, false);
}

以前可以通过window.event读取鼠标位置,但现在已弃用。