如何在没有事件的情况下获取鼠标位置(不移动鼠标)?

IT技术 javascript mouseevent dom-events
2021-01-27 03:29:33

在没有任何鼠标移动事件(不移动鼠标)的情况下,是否可以在页面加载后使用 JavaScript 获取鼠标位置?

6个回答

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

好的,我刚刚想到了一个方法。用覆盖整个文档的 div 覆盖您的页面。在里面,创建(比如说)2,000 x 2,000 个<a>元素(这样:hover伪类可以在 IE 6 中工作,见),每个 1 像素大小。:hover为那些<a>改变属性的元素创建一个 CSS规则(比方说font-family)。在您的负载处理程序中,循环浏览 400 万个<a>元素中的每一个,检查currentStyle/getComputedStyle()直到找到带有悬停字体的元素从此元素推断回来以获取文档中的坐标。

注意不要这样做

也许这可以通过二分搜索来实现?循环制作一对<a>覆盖给定矩形的<img>元素(我想使用大小元素的绝对定位),每次缩小矩形。是的,这很荒谬,但是在第一次鼠标移动之前无法获得此信息。
2021-03-13 03:29:33
哈哈 - 在某些时候你应该谷歌一下,看看你是否能弄清楚有多少人实际实施了这个
2021-03-18 03:29:33
实际上,它无需太多 CPU 负载即可实现(我认为。我还没有测试过)。在 dom 准备好用 javascript 构建 <a> 元素,采取鼠标位置,然后删除所有 <a> 元素。在 mousemouse 上,您应该有其他功能来获取鼠标位置。无论如何,这很有趣。
2021-03-26 03:29:33
@DariusBacon:链接的答案似乎不正确:jsbin.com/utocax/3所以是的,这种方法在某些情况下可能是实用的。
2021-03-31 03:29:33
stackoverflow.com/a/8543879/27024说在鼠标第一次移动之前悬停也不会触发。这挫败了这个计划。
2021-04-03 03:29:33

2020 年编辑:不再起作用。似乎是这样,浏览器供应商对此进行了修补。因为大多数浏览器都依赖于铬,所以它可能是其核心。

旧答案:您还可以挂钩 mouseenter (当鼠标光标位于页面内时,页面重新加载后会触发此事件)。扩展 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。因此,您可以使用光标检查用户是否在您的页面上。

chrome 68,使用上面的 jsfiddel,在第一次移动鼠标而不是加载时发生警报,​​即使鼠标在页面完成加载之前移动到渲染区域也是如此。
2021-03-14 03:29:33
这似乎是这里唯一真正有用的答案,这似乎很奇怪。实际上(在最新的 Firefox、Chrome 和 IE11 中)mouseenter 会在页面加载时触发并提供正确的坐标。在过去几年中,该领域的浏览器行为是否发生了简单的变化?
2021-03-21 03:29:33
@Proton:在页面完全加载之前将鼠标移到结果面板的结果面板区域,不要移动。加载页面后立即知道鼠标的位置。不需要鼠标移动。因此,当页面已加载且鼠标位于文档区域内时,mouseenter 也会被触发。也就是说,OP 最初想要什么。没有其他人提供这个答案。
2021-03-22 03:29:33
一个潜在有用的补充是为mouseleave事件添加一个函数,该函数设置xy返回到null'undefined'
2021-03-30 03:29:33
事实上,“mouseenter”似乎没有增加任何value。我在 Chrome 和 IE 中使用以下 jsfiddle 进行了测试,直到您将鼠标放在内部文档(结果面板)上时,它们才会显示坐标jsfiddle.net/xkpd784o/1
2021-04-09 03:29:33

您可以做的是为光标的坐标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);}

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

@Pichan 这对我没有好处,因为我一直在寻找一种cursorX/Y在任何事件发生之前填充这些变量的方法
2021-03-13 03:29:33
小心,保留一个 mousemove 侦听器可能会很昂贵。我建议在间隔中重新创建侦听器并在获得坐标后销毁侦听器。
2021-03-17 03:29:33
你读过这篇文章的主题吗?OP 询问如何在不使用事件的情况下获取鼠标坐标。然而,您的帖子建议使用 onmousemove 事件。
2021-03-21 03:29:33
很少有用户不会触发鼠标事件
2021-03-30 03:29:33
@jake 尽管 OP 专门要求使用非事件方法,但此答案有益于来到这里寻找答案和可能的解决方法的其他人。另外,我会在主题中部分考虑这个答案,因为据我所知,这是在任何给定时间获取光标位置而无需直接使用事件的最佳方法。也就是说,答案的措辞可以更符合陈述事实并提供避免在评论中吹毛求疵的方法。
2021-04-02 03:29:33

如果您渲染 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>元素:

  • 第 1 步:将整个屏幕视为起始搜索区域
  • 第 2 步:将搜索区域拆分为 2 x 2 = 4 个矩形 <a>元素
  • 第 3 步:使用getComputedStyle()函数确定鼠标悬停在哪个矩形中
  • 第 4 步:将搜索区域缩小到那个矩形并从第 2 步开始重复。

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

因此,您将生成最多 11 x 4 = 44 个<a>元素。

如果您不需要精确地将鼠标位置确定为一个像素,但说 10px 精度就可以了。您最多可以重复这些步骤 8 次,因此您最多需要绘制 8 x 4 = 32 个<a>元素。

<a>由于 DOM 通常很慢,因此生成然后销毁元素也不会执行。相反,您可以仅重用最初的 4 个<a>元素在循环执行步骤时调整它们的top, left,widthheight

现在,创建 4<a>也是一种矫枉过正。相反,您可以在每个矩形中<a>进行测试时重复使用相同的一个元素getComputedStyle()因此,不要将搜索区域拆分为 2 x 2<a>元素,只需<a>通过使用topleft样式属性移动它来重用单个元素

所以,你需要的是一个单一的<a>元素来改变它widthheight最大11倍,并改变其topleft最大44倍,你将有确切的鼠标位置。

您可以尝试类似于 Tim Down 建议的方法 - 但不要为屏幕上的每个像素设置元素,只需创建 2-4 个元素(框),并动态更改它们的位置、宽度、高度以划分屏幕上可能的位置通过2-4递归,从而快速找到鼠标的真实位置。

例如 - 第一个元素占据屏幕的左右半部分,然后是上半部分和下半部分。现在我们已经知道鼠标位于屏幕的哪四分之一,可以重复 - 发现这个空间的哪四分之一......