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

时间:2010-04-08 15:17:55

标签: javascript javascript-events mouseevent

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

14 个答案:

答案 0 :(得分:303)

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

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

N.B。 不要这样做

答案 1 :(得分:109)

您还可以挂钩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。因此,您可以使用光标检查用户是否在您的页面上。

答案 2 :(得分:79)

您可以做的是为光标的xy坐标创建变量,每当鼠标移动时更新它们,并在一定间隔内调用函数,以便根据存储位置执行所需操作

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

var cursorX;
var cursorY;
document.onmousemove = function(e){
    cursorX = e.pageX;
    cursorY = e.pageY;
}
setInterval(checkCursor, 1000);
function checkCursor(){
    alert("Cursor at: " + cursorX + ", " + cursorY);
}

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

答案 3 :(得分:9)

你可以尝试类似于Tim Down建议的东西 - 但不是为屏幕上的每个像素添加元素,而是创建2-4个元素(盒子),并动态地改变它们的位置,宽度,高度以划分可能性屏幕上的位置递归2-4,从而快速找到鼠标的真实位置。

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

答案 4 :(得分:4)

如果你渲染2,000 x 2,000 <a>个元素,@ Timim的答案就不会有效:

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

     

N.B。不要这样做。

但是你不必一次渲染400万个元素,而是使用二进制搜索。只需使用4个<a>元素:

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

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

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

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

同样生成然后销毁<a>元素并不适用,因为DOM通常很慢。相反,您可以重复使用最初的4个<a>元素,并在循环执行步骤时调整他们的topleftwidthheight

现在,创建4 <a>也是一种过度杀伤力。相反,您可以在每个矩形中测试<a>时重复使用相同的getComputedStyle()元素。因此,不是将搜索区域拆分为2 x 2 <a>元素,而是通过使用<a>top样式属性移动它来重用单个left元素。

因此,您只需要一个<a>元素将其widthheight最多更改11次,并更改其topleft最多44时间,你将有确切的鼠标位置。

答案 5 :(得分:2)

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

您可以在父页面上使用JHarding代码,以便最终位置始终在全局变量中可用:

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

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

答案 6 :(得分:2)

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

if( is_home() || is_front_page() ) {
   get_template_part( 'template-parts/album-grid', 'index' );
}

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

答案 7 :(得分:1)

我实现了一个水平/垂直搜索,(首先制作一个div水平排列的垂直线链接,然后制作一个垂直排列的div水平线链接,并简单地看看哪个具有悬停状态)就像Tim Down的想法以上,它的工作速度非常快。可悲的是,在KDE上的Chrome 32上无效。

jsfiddle.net/5XzeE/4 /

答案 8 :(得分:1)

您无需移动鼠标即可获取光标的位置。此位置也会报告 mousemove 以外的事件。以下是点击事件

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

答案 9 :(得分:1)

这是我的解决方案。它导出可以在任何地方使用的 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

答案 10 :(得分:0)

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

答案 11 :(得分:0)

重复@SuperNova's answer,这是一种使用ES6类的方法,可以在回调中保持this的上下文正确:

&#13;
&#13;
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));
&#13;
&#13;
&#13;

答案 12 :(得分:0)

我认为我可能有一个不计div和像素的合理解决方案。.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);
}  

答案 13 :(得分:0)

不是鼠标位置,但是,如果要查找当前光标位置(用于获取最后键入的字符等用例),则在以下代码段中可以正常工作。
这将为您提供与文本内容相关的光标索引。

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