Javascript - Verfolgen Sie die Mausposition

160

Ich hoffe, die Position des Mauszeigers periodisch alle t Sekunden zu verfolgen. Wenn also eine Seite geladen wird - dieser Tracker sollte starten und etwa 100 ms lang sollte ich den neuen Wert von posX und posY erhalten und ihn im Formular ausdrucken.

Ich habe den folgenden Code ausprobiert - aber die Werte werden nicht aktualisiert - nur die Anfangswerte von posX und posY werden in den Formularfeldern angezeigt. Irgendwelche Ideen, wie ich das zum Laufen bringen kann?

<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>
Hari
quelle
Das Problem ist, dass es kein eventObjekt gibt, wenn die Funktion zum zweiten Mal aufgerufen wird. Sie sollten sich wahrscheinlich ein Ereignis anhören, als es zu verwenden setTimeout.
Felix Kling
Ja, aber sollte sich die Funktion mouse_position () nicht alle 100 Millisekunden selbst aufrufen. Sollte es sich nicht tatsächlich wie eine unendliche rekursive Funktion verhalten?
Hari
2
Mögliches Duplikat der Position
Shadow Wizard ist Ear For You
@Titan: Ja, aber ich vermute , dass es Fehler , weil window.eventsein wird undefinedoder null. Wenn es kein Ereignis gibt, gibt es kein eventObjekt.
Felix Kling
1
Was ist aus Interesse die Anwendung davon?
SuperUberDuper

Antworten:

178

Die Position der Maus wird auf dem eventObjekt angezeigt mousemove, das von einem Handler für das Ereignis empfangen wurde und das Sie an das Fenster anhängen können (die Ereignisblasen):

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

(Beachten Sie, dass der Hauptteil davon ifnur auf dem alten IE ausgeführt wird.)

Beispiel für das oben Genannte in Aktion - Es zeichnet Punkte, wenn Sie mit der Maus über die Seite ziehen. (Getestet auf IE8, IE11, Firefox 30, Chrome 38.)

Wenn Sie wirklich eine Timer-basierte Lösung benötigen, kombinieren Sie diese mit einigen Statusvariablen:

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

Soweit mir bekannt ist, können Sie die Mausposition nicht ermitteln, ohne ein Ereignis gesehen zu haben. Dies scheint diese Antwort auf eine andere Frage zum Stapelüberlauf zu bestätigen.

Randnotiz : Wenn Sie alle 100 ms (10 Mal / Sekunde) etwas tun, versuchen Sie, die tatsächliche Verarbeitung, die Sie in dieser Funktion ausführen, sehr, sehr begrenzt zu halten . Das ist eine Menge Arbeit für den Browser, insbesondere für ältere Microsoft-Browser. Ja, auf modernen Computern scheint es nicht viel zu sein, aber in Browsern ist viel los ... So können Sie beispielsweise die zuletzt verarbeitete Position verfolgen und sofort vom Handler abspringen, wenn die Position nicht vorhanden ist. t geändert.

TJ Crowder
quelle
66

Hier ist eine Lösung, die auf jQuery und einem Mausereignis-Listener (der weitaus besser ist als eine normale Abfrage) für den Körper basiert:

$("body").mousemove(function(e) {
    document.Form1.posx.value = e.pageX;
    document.Form1.posy.value = e.pageY;
})
Solendil
quelle
Wie ich bereits erwähnt hatte, ist die regelmäßige Abstimmung genau das, was ich tun möchte. Ich verfolge keine Änderungen an Mausereignissen, sondern versuche nur, die Mausposition alle x Millisekunden zu erfassen (unabhängig davon, ob sich die Maus bewegt hat oder nicht).
Hari
3
Warum hat sich das Verfolgen eines Werts, den Sie sicher kennen, nicht geändert? Ich verstehe nicht, es sei denn, es ist ein Hausaufgabenproblem. Mit der Ereignismethode können Sie jede Änderung dieser Werte verfolgen und dann an anderer Stelle eine 100-ms-Abfrage durchführen, wenn Sie diese Werte für einen beliebigen Zweck verarbeiten müssen.
Solendil
1
Es gibt keinen Vorteil, jQuery hier zu verwenden, außer unnötigerweise eine 5-MB-JS-
Bibliothek zu verwenden
@ PattycakeJr Das letzte Mal, als ich es sah, war es unter 90 KB in der minimierten Version
Kris
1
@PattycakeJr auch wenn Sie Super unwahrscheinlich Herunterladen es überhaupt , wenn man da fast alle anderen Seiten Links zu es zu einem CDN Punkt
Brian Leishman
53
onmousemove = function(e){console.log("mouse location:", e.clientX, e.clientY)}

Öffnen Sie Ihre Konsole ( Ctrl+ Shift+ J), kopieren Sie den obigen Code und bewegen Sie die Maus im Browserfenster.

RegarBoy
quelle
1
Imo die beste Antwort
HereHere
10

Ich glaube, dass wir das überdenken,

function mouse_position(e)
{
//do stuff
}
<body onmousemove="mouse_position(event)"></body>

dGRAMOP
quelle
1
Ich bin neu in diesem Forum, also nur damit ich weiß, bitte erkläre, warum du - und meine Markise - das ist, damit ich nicht wieder den gleichen Fehler mache. Vielen Dank! ThePROgrammer
dGRAMOP
10
Auch ich ärgere mich über Abstimmungen ohne Erklärung. Um Ihnen eine mögliche Erklärung zu geben, geht diese Antwort nicht auf das Problem des OP ein, alle 100 ms abzufragen. In seiner Antwort auf andere Antworten wird klarer, dass dies eine Notwendigkeit ist.
aaaaaa
1
Auch diese Art der Inline-Ereignisbehandlung ist meines Erachtens veraltet. document.body.addEventListener("mousemove", function (e) {})ist der Weg, dies zu tun, in Ihrem Javascript-Code im Gegensatz zu im HTML
Ryan
10

Was ich denke, dass er nur die X / Y-Positionen des Cursors wissen möchte, als warum die Antwort so kompliziert ist.

// 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>

Murtaza
quelle
5

ES6-basierter Code:

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

document.addEventListener('mousemove', handleMousemove);

Wenn Sie zum Bewegen der Maus eine Drosselung benötigen, verwenden Sie diese:

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

Hier ist ein Beispiel

oboshto
quelle
2

Unabhängig vom Browser haben die folgenden Zeilen für mich funktioniert, um die korrekte Mausposition abzurufen.

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

Sai Ganesh Pittala
quelle
2

Wenn Sie die Mausbewegung nur visuell verfolgen möchten:

<!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>

luistar15
quelle
2

Ich habe nicht genug Ruf, um eine Kommentarantwort zu posten, aber ich habe die ausgezeichnete Antwort von TJ Crowder genommen und den Code auf einem 100-ms-Timer vollständig definiert . (Er überließ einige Details der Fantasie.)

Danke OP für die Frage und TJ für die Antwort! Sie sind beide eine große Hilfe. Der Code ist unten als Spiegel von isbin eingebettet.

<!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>

Kris mit einem K.
quelle
0

Hier ist eine Kombination der beiden Anforderungen: Verfolgen Sie die Mausposition alle 100 Millisekunden:

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

Diese Tracks & wirkt auf die Mausposition, aber nur alle Zeit Millisekunden.

Bobby Jack
quelle
0

Nur eine vereinfachte Version von @TJ Crowder und @RegarBoy .

Weniger ist meiner Meinung nach mehr.

Weitere Informationen zum Ereignis finden Sie unter onmousemove event.

Bildmaus-Tracker

Es gibt einen neuen Wert von posXund posYjedes Mal, wenn sich die Maus entsprechend den horizontalen und vertikalen Koordinaten bewegt.

<!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>
Jonas
quelle