【问题标题】:Javascript - Track mouse positionJavascript - 跟踪鼠标位置
【发布时间】:2011-12-09 02:18:25
【问题描述】:

我希望每隔 t 毫秒定期跟踪鼠标光标的位置。所以本质上,当一个页面加载时——这个跟踪器应该启动并且(比如说)每 100 毫秒,我应该得到 posX 和 posY 的新值并在表单中打印出来。

我尝试了以下代码 - 但值没有被刷新 - 只有 posX 和 posY 的初始值显示在表单框中。关于如何启动并运行它的任何想法?

<html>
<head>
<title> Track Mouse </title>
<script type="text/javascript">
function mouse_position()
{
    var e = window.event;

    var posX = e.clientX;
    var posY = e.clientY;

    document.Form1.posx.value = posX;
    document.Form1.posy.value = posY;

    var t = setTimeout(mouse_position,100);

}
</script>

</head>

<body onload="mouse_position()">
<form name="Form1">
POSX: <input type="text" name="posx"><br>
POSY: <input type="text" name="posy"><br>
</form>
</body>
</html>

【问题讨论】:

  • 问题是第二次调用函数时不会有event对象。您可能应该听一些事件而不是使用setTimeout
  • 是的,但是 mouse_position() 函数不应该每隔 100 毫秒就调用一次。它实际上不应该表现得像一个无限递归函数吗?
  • @Titan:是的,但我怀疑它会出错,因为window.event 将是undefinednull。如果没有事件,则没有event 对象。
  • 出于兴趣,这有什么应用?

标签: javascript


【解决方案1】:

鼠标的位置在mousemove 事件的处理程序接收到的event 对象上报告,您可以将其附加到窗口(事件冒泡):

(function() {
    document.onmousemove = handleMouseMove;
    function handleMouseMove(event) {
        var eventDoc, doc, body;

        event = event || window.event; // IE-ism

        // If pageX/Y aren't available and clientX/Y are,
        // calculate pageX/Y - logic taken from jQuery.
        // (This is to support old IE)
        if (event.pageX == null && event.clientX != null) {
            eventDoc = (event.target && event.target.ownerDocument) || document;
            doc = eventDoc.documentElement;
            body = eventDoc.body;

            event.pageX = event.clientX +
              (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
              (doc && doc.clientLeft || body && body.clientLeft || 0);
            event.pageY = event.clientY +
              (doc && doc.scrollTop  || body && body.scrollTop  || 0) -
              (doc && doc.clientTop  || body && body.clientTop  || 0 );
        }

        // Use event.pageX / event.pageY here
    }
})();

(请注意,if 的主体只能在旧 IE 上运行。)

Example of the above in action - 当您将鼠标拖到页面上时,它会绘制点。 (在 IE8、IE11、Firefox 30、Chrome 38 上测试。)

如果您确实需要基于计时器的解决方案,可以将其与一些状态变量结合使用:

(function() {
    var mousePos;

    document.onmousemove = handleMouseMove;
    setInterval(getMousePosition, 100); // setInterval repeats every X ms

    function handleMouseMove(event) {
        var dot, eventDoc, doc, body, pageX, pageY;

        event = event || window.event; // IE-ism

        // If pageX/Y aren't available and clientX/Y are,
        // calculate pageX/Y - logic taken from jQuery.
        // (This is to support old IE)
        if (event.pageX == null && event.clientX != null) {
            eventDoc = (event.target && event.target.ownerDocument) || document;
            doc = eventDoc.documentElement;
            body = eventDoc.body;

            event.pageX = event.clientX +
              (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
              (doc && doc.clientLeft || body && body.clientLeft || 0);
            event.pageY = event.clientY +
              (doc && doc.scrollTop  || body && body.scrollTop  || 0) -
              (doc && doc.clientTop  || body && body.clientTop  || 0 );
        }

        mousePos = {
            x: event.pageX,
            y: event.pageY
        };
    }
    function getMousePosition() {
        var pos = mousePos;
        if (!pos) {
            // We haven't seen any movement yet
        }
        else {
            // Use pos.x and pos.y
        }
    }
})();

据我所知,您无法在没有看到事件的情况下获得鼠标位置,this answer to another Stack Overflow question 似乎证实了这一点。

旁注:如果您打算每 100 毫秒(10 次/秒)执行一次操作,请尽量保持您在该函数中执行的实际处理非常非常有限时间>。这对浏览器来说是很多工作,尤其是旧的微软浏览器。是的,在现代计算机上看起来并不多,但在浏览器中发生了很多事情......因此,例如,您可能会跟踪您处理的最后一个位置,如果该位置没有,则立即从处理程序中保释。没变。

【讨论】:

  • 现在可以安全地使用 pageX/Y、clientX/Y 和 screenX/Y。 IE 很快就会被遗忘,所以它比这简单得多。
【解决方案2】:

这是一个解决方案,基于 jQuery 和 body 上的鼠标事件侦听器(比常规轮询要好得多):

$("body").mousemove(function(e) {
    document.Form1.posx.value = e.pageX;
    document.Form1.posy.value = e.pageY;
})

【讨论】:

  • 正如我所提到的,定期轮询正是我想要做的。我没有跟踪鼠标事件的变化,我只想每 x 毫秒捕获一次鼠标位置(无论鼠标是否移动)。
  • 为什么要跟踪一个您确定没有改变的值?我不明白,除非是作业问题。使用 event 方法,您可以跟踪这些值的每一次更改,然后如果您出于任何目的需要处理这些值,请在其他地方进行 100 毫秒轮询。
  • 这里使用 jQuery 没有任何好处,除非不必要地使用 5mb JS lib
  • @PattycakeJr 上次我查看的缩小版小于 90kB
  • @PattycakeJr 如果你 super 如果你指向 CDN 根本不可能下载它,因为几乎所有其他网站都链接到它
【解决方案3】:

我认为我们想太多了,

function mouse_position(e)
{
//do stuff
}
&lt;body onmousemove="mouse_position(event)"&gt;&lt;/body&gt;

【讨论】:

  • 我是这个论坛的新手,所以我知道,请解释为什么你 -1nd 我的 awnser - 这样我就不会再犯同样的错误了。谢谢!程序员
  • 我也对没有任何解释的反对票感到恼火。为了给你一个可能的解释,这个答案并没有解决 OP 每 100 毫秒轮询一次的问题。在他对其他答案的回答中更清楚地表明这是必要的。
  • 我相信这种内联事件处理也已被弃用。 document.body.addEventListener("mousemove", function (e) {}) 是这样做的方法,在你的 javascript 代码中而不是在 html 中
【解决方案4】:
onmousemove = function(e){console.log("mouse location:", e.clientX, e.clientY)}

打开您的控制台 (Ctrl+Shift+J),复制粘贴上面的代码,然后在浏览器窗口上移动鼠标。

【讨论】:

  • 最好的答案
  • onmousemove = function(e){console.log(`mouse location = X: ${e.x}, Y: ${e.y}`)}
【解决方案5】:

我认为他只想知道光标的X/Y位置而不是答案为什么那么复杂。

// Getting 'Info' div in js hands
var info = document.getElementById('info');

// Creating function that will tell the position of cursor
// PageX and PageY will getting position values and show them in P
function tellPos(p){
  info.innerHTML = 'Position X : ' + p.pageX + '<br />Position Y : ' + p.pageY;
}
addEventListener('mousemove', tellPos, false);
* {
  padding: 0:
  margin: 0;
  /*transition: 0.2s all ease;*/
  }
#info {
  position: absolute;
  top: 10px;
  right: 10px;
  background-color: black;
  color: white;
  padding: 25px 50px;
}
<!DOCTYPE html>
<html>
  
  <body>
    <div id='info'></div>
        </body>
  </html>

【讨论】:

  • 简单是没有代价的!!!
【解决方案6】:

不管浏览器如何,下面的行都可以帮助我获取正确的鼠标位置。

event.clientX - event.currentTarget.getBoundingClientRect().left event.clientY - event.currentTarget.getBoundingClientRect().top

【讨论】:

    【解决方案7】:

    基于 ES6 的代码:

    let handleMousemove = (event) => {
      console.log(`mouse position: ${event.x}:${event.y}`);
    };
    
    document.addEventListener('mousemove', handleMousemove);
    

    如果您需要限制鼠标移动,请使用:

    let handleMousemove = (event) => {
      console.warn(`${event.x}:${event.y}\n`);
    };
    
    let throttle = (func, delay) => {
      let prev = Date.now() - delay;
      return (...args) => {
        let current = Date.now();
        if (current - prev >= delay) {
          prev = current;
          func.apply(null, args);
        }
      }
    };
    
    // let's handle mousemoving every 500ms only
    document.addEventListener('mousemove', throttle(handleMousemove, 500));
    

    这里是example

    【讨论】:

      【解决方案8】:

      如果只是想直观地跟踪鼠标移动:

      <!DOCTYPE html>
      <html>
      <head>
      <title></title>
      </head>
      <style type="text/css">
      * { margin: 0; padding: 0; }
      html, body { width: 100%; height: 100%; overflow: hidden; }
      </style>
      <body>
      <canvas></canvas>
      
      <script type="text/javascript">
      var
      canvas    = document.querySelector('canvas'),
      ctx       = canvas.getContext('2d'),
      beginPath = false;
      
      canvas.width  = window.innerWidth;
      canvas.height = window.innerHeight;
      
      document.body.addEventListener('mousemove', function (event) {
      	var x = event.clientX, y = event.clientY;
      
      	if (beginPath) {
      		ctx.lineTo(x, y);
      		ctx.stroke();
      	} else {
      		ctx.beginPath();
      		ctx.moveTo(x, y);
      		beginPath = true;
      	}
      }, false);
      </script>
      </body>
      </html>

      【讨论】:

        【解决方案9】:

        这是两个要求的组合:每 100 毫秒跟踪鼠标位置:

        var period = 100,
            tracking;
        
        window.addEventListener("mousemove", function(e) {
            if (!tracking) {
                return;
            }
        
            console.log("mouse location:", e.clientX, e.clientY)
            schedule();
        });
        
        schedule();
        
        function schedule() {
            tracking = false;
        
            setTimeout(function() {
                tracking = true;
            }, period);
        }
        

        这会跟踪并作用于鼠标位置,但仅每 周期 毫秒。

        【讨论】:

          【解决方案10】:

          我没有足够的声誉来发表评论回复,但我接受了 TJ Crowder 的 excellent answer 和完全定义的 the code on a 100ms timer。 (他把一些细节留给想象。)

          感谢 OP 的提问,感谢 TJ 的回答!你们俩都是很大的帮助。代码嵌入下面作为 isbin 的镜像。

          <!DOCTYPE html>
          <html>
          <head>
            <meta charset="utf-8">
            <title>Example</title>
            <style>
              body {
                height: 3000px;
              }
              .dot {
                width: 2px;
                height: 2px;
                background-color: black;
                position: absolute;
              }
            </style>
          </head>
          <body>
          <script>
          (function() {
              "use strict";
              var mousePos;
          
              document.onmousemove = handleMouseMove;
              setInterval(getMousePosition, 100); // setInterval repeats every X ms
          
              function handleMouseMove(event) {
                  var eventDoc, doc, body;
          
                  event = event || window.event; // IE-ism
          
                  // If pageX/Y aren't available and clientX/Y are,
                  // calculate pageX/Y - logic taken from jQuery.
                  // (This is to support old IE)
                  if (event.pageX == null && event.clientX != null) {
                      eventDoc = (event.target && event.target.ownerDocument) || document;
                      doc = eventDoc.documentElement;
                      body = eventDoc.body;
          
                      event.pageX = event.clientX +
                        (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
                        (doc && doc.clientLeft || body && body.clientLeft || 0);
                      event.pageY = event.clientY +
                        (doc && doc.scrollTop  || body && body.scrollTop  || 0) -
                        (doc && doc.clientTop  || body && body.clientTop  || 0 );
                  }
          
                  mousePos = {
                      x: event.pageX,
                      y: event.pageY
                  };
              }
              function getMousePosition() {
                  var pos = mousePos;
          		
                  if (!pos) {
                      // We haven't seen any movement yet, so don't add a duplicate dot 
                  }
                  else {
                      // Use pos.x and pos.y
                      // Add a dot to follow the cursor
                      var dot;
                      dot = document.createElement('div');
                      dot.className = "dot";
                      dot.style.left = pos.x + "px";
                      dot.style.top = pos.y + "px";
                      document.body.appendChild(dot);
                  }
              }
          })();
          </script>
          </body>
          </html>

          【讨论】:

            【解决方案11】:

            只是@T.J. Crowder@RegarBoy 答案的简化版本。

            在我看来,少即是多。

            查看onmousemove event 了解有关活动的更多信息。

            每次鼠标按横纵坐标移动时,都会有一个新的值posXposY

            <!DOCTYPE html>
                <html>
                <head>
                  <meta charset="utf-8">
                  <title>Example Mouse Tracker</title>
                  <style>    
                    body {height: 3000px;}
                    .dot {width: 2px;height: 2px;background-color: black;position: absolute;}
                  </style>
                </head>
                <body>
                <p>Mouse tracker</p>
                <script>
                onmousemove = function(e){
                    //Logging purposes
                    console.log("mouse location:", e.clientX, e.clientY);
            
                    //meat and potatoes of the snippet
                    var pos = e;
                    var dot;
                    dot = document.createElement('div');
                    dot.className = "dot";
                    dot.style.left = pos.x + "px";
                    dot.style.top = pos.y + "px";
                    document.body.appendChild(dot);
                }      
                </script>
                </body>
                </html>
            

            【讨论】:

            • 干得好,当我们快速移动鼠标时,你有什么技巧可以让我们更有意义吗?更快的是运动,最大的是2点之间的差距。可以减少吗?
            • @Matrix 您可能可以计算最后一点和当前点之间的直线并用点填充该线。
            【解决方案12】:

            这是跟踪鼠标位置的最简单方法

            HTML

            <body id="mouse-position" ></body>
            

            js

            document.querySelector('#mouse-position').addEventListener('mousemove', (e) => {
                    console.log("mouse move X: ", e.clientX);
                    console.log("mouse move X: ", e.screenX);
            
            
                }, );
            

            know more

            【讨论】:

              【解决方案13】:

              我们最近必须找到当前的 x,y 位置来枚举光标悬停在其上的元素,而与 z-index 无关。我们最终只是将 mousemove 事件侦听器附加到文档,例如,

              function findElements(e) {
                var els = document.elementsFromPoint(e.clientX, e.clientY);
              
                // do cool stuff with els
                console.log(els);
              
                return;
              }
              
              document.addEventListener("mousemove", findElements);

              【讨论】:

                【解决方案14】:

                这是获取鼠标指针坐标的最短途径。 只需将您的元素放在光标要悬停的位置,$("")

                 $("***enter you element here***").mousemove(function(event)
                {
                 console.clear()
                  var x = event.originalEvent.screenX;
                  var y = event.originalEvent.screenY;
                  console.log("x : "+x)
                  console.log("y : "+y)
                })
                

                【讨论】:

                  【解决方案15】:

                  这是一个解决方案

                  document.onmousemove = showCoords;
                  function showCoords(event) {
                  var x = event.clientX;
                  var y = event.clientY;
                  var coords = "X coords: " + x + ", Y coords: " + y;
                  document.getElementById("box1").innerHTML = coords;
                  }
                  

                  【讨论】:

                    【解决方案16】:

                    document.addEventListener('mousemove', (event) => {
                      document.getElementById("line").style.top = event.clientY - 10 + 'px';
                      document.getElementById("lineY").style.left = event.clientX - 10 + 'px';
                      document.getElementById("pos").style.top = (event.clientY - 60) + 'px';
                      document.getElementById("pos").style.left = (event.clientX - 60) + 'px';
                    });
                    body {
                      position: relative;
                      height: auto;
                      min-height: 100% !important;
                      background-color: lightblue;
                    }
                    
                    h1 {
                      color: white;
                      text-align: center;
                    }
                    
                    p {
                      font-family: verdana;
                      font-size: 20px;
                    }
                    
                    .abs {
                      position: relative;
                    }
                    
                    .lineY {
                      display: flex;
                      position: relative;
                      left: 0px;
                      background-color: black;
                      width: 2px;
                      height: 100vh;
                      min-height: 100%
                    }
                    
                    .line {
                      display: flex;
                      position: relative;
                      background-color: black;
                      min-height: 2px;
                      width: 100%;
                    }
                    
                    .circle {
                      display: flex;
                      position: absolute;
                      left: 0px;
                      top: 0px;
                    }
                    <div class='line' id="line"></div>
                    <div class='lineY' id="lineY"></div>
                    <svg height="100" width="100" id="pos" class="circle">
                      <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="transparent" />
                    </svg>

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2014-12-13
                      • 2012-07-03
                      • 2013-12-08
                      • 1970-01-01
                      • 2021-01-30
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多