Javascript - Lacak posisi mouse


161

Saya berharap untuk melacak posisi kursor mouse, secara berkala setiap detik. Jadi pada dasarnya, ketika sebuah halaman dimuat - pelacak ini harus dimulai dan untuk (katakanlah) setiap 100 ms, saya harus mendapatkan nilai baru posX dan posY dan mencetaknya dalam formulir.

Saya mencoba kode berikut - tetapi nilainya tidak disegarkan - hanya nilai awal dari posX dan posY yang muncul di kotak formulir. Ada ide tentang bagaimana saya bisa menjalankan dan menjalankan ini?

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

Masalahnya adalah bahwa tidak akan ada eventobjek saat fungsi dipanggil untuk kedua kalinya. Anda mungkin harus mendengarkan acara daripada menggunakan setTimeout.
Felix Kling

Ya, tetapi tidak seharusnya fungsi mouse_position () terus memanggil dirinya sendiri setiap 100 milidetik. Bukankah seharusnya itu berperilaku seperti fungsi rekursif yang tak terbatas?
Hari


@ Titan: Ya, tapi saya menduga itu akan salah karena window.eventakan undefinedatau null. Jika tidak ada acara, tidak ada eventobjek.
Felix Kling

1
karena ketertarikan, apa aplikasi ini?
SuperUberDuper

Jawaban:


178

Posisi mouse dilaporkan pada eventobjek yang diterima oleh pawang untuk mousemoveacara tersebut, yang dapat Anda lampirkan ke jendela (gelembung acara):

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

(Perhatikan bahwa tubuh itu ifhanya akan berjalan di IE lama.)

Contoh tindakan di atas - ia menarik titik saat Anda menyeret mouse ke halaman. (Diuji pada IE8, IE11, Firefox 30, Chrome 38.)

Jika Anda benar-benar membutuhkan solusi berbasis waktu, Anda menggabungkan ini dengan beberapa variabel status:

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

Sejauh yang saya ketahui, Anda tidak bisa mendapatkan posisi mouse tanpa melihat suatu peristiwa, sesuatu yang sepertinya dikonfirmasi oleh jawaban atas pertanyaan Stack Overflow ini .

Catatan : Jika Anda akan melakukan sesuatu setiap 100 ms (10 kali / detik), cobalah untuk menjaga proses aktual yang Anda lakukan dalam fungsi itu sangat, sangat terbatas . Itu banyak pekerjaan untuk browser, terutama yang lebih lama Microsoft. Ya, pada komputer modern sepertinya tidak banyak, tetapi ada banyak hal yang terjadi di browser ... Jadi misalnya, Anda dapat melacak posisi terakhir yang Anda proses dan segera menebus jaminan dari pawang jika posisinya belum t berubah.


66

Berikut ini solusinya, berdasarkan jQuery dan pendengar acara mouse (yang jauh lebih baik daripada polling biasa) di badan:

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

Seperti yang saya sebutkan, pemungutan suara reguler adalah persis apa yang ingin saya lakukan. Saya tidak melacak perubahan dalam peristiwa mouse, saya hanya mencari untuk menangkap posisi mouse setiap x milidetik (terlepas dari apakah mouse bergerak atau tidak).
Hari

3
Mengapa melacak nilai yang Anda tahu pasti tidak berubah? Saya tidak mengerti, kecuali itu adalah masalah pekerjaan rumah. Dengan metode peristiwa, Anda dapat melacak setiap perubahan nilai-nilai ini, kemudian melakukan polling 100 ms di tempat lain jika Anda perlu menangani nilai-nilai ini untuk tujuan apa pun.
solendil

1
Tidak ada keuntungan menggunakan jQuery di sini kecuali tidak perlu menggunakan JS JSB 5mb
Pattycake Jr

@PattycakeJr Terakhir kali saya melihat di bawah 90kB dalam versi minified
Kris

1
@PattycakeJr juga jika Anda sangat tidak mungkin mengunduhnya sama sekali jika Anda menunjuk ke CDN karena hampir setiap situs lain menautkannya
Brian Leishman

53
onmousemove = function(e){console.log("mouse location:", e.clientX, e.clientY)}

Buka konsol Anda ( Ctrl+ Shift+ J), salin-tempel kode di atas dan gerakkan mouse Anda di jendela browser.


1
Imo jawaban terbaik
Sini

10

Saya percaya bahwa kita terlalu memikirkan ini,

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


1
Saya baru di forum ini, jadi saya hanya tahu, tolong jelaskan mengapa Anda -1 awnser saya - ini jadi saya tidak membuat kesalahan yang sama lagi. Terima kasih! ThePROgrammer
dGRAMOP

10
Saya juga merasa terganggu oleh downvotes tanpa penjelasan. Untuk memberi Anda kemungkinan penjelasan, jawaban ini tidak membahas masalah OP tentang polling setiap 100 ms. Lebih jelas dalam tanggapannya terhadap jawaban lain bahwa ini adalah keharusan.
aaaaaa

1
juga penanganan event inline semacam ini sudah usang saya percaya. document.body.addEventListener("mousemove", function (e) {})adalah cara untuk melakukan ini, dalam kode javascript Anda sebagai lawan dalam html
Ryan

10

Apa yang saya pikirkan bahwa dia hanya ingin mengetahui posisi kursor X / Y daripada mengapa jawabannya rumit.

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


5

Kode berbasis ES6:

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

document.addEventListener('mousemove', handleMousemove);

Jika Anda perlu pelambatan untuk mousemoving, gunakan ini:

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

di sini adalah contoh


2

Terlepas dari peramban, baris di bawah ini berfungsi agar saya mengambil posisi mouse yang benar.

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


2

Jika hanya ingin melacak pergerakan mouse secara visual:

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


2

Saya tidak memiliki reputasi yang cukup untuk mengirim balasan komentar, tetapi mengambil jawaban luar biasa TJ Crowder dan sepenuhnya mendefinisikan kode pada timer 100ms . (Dia meninggalkan beberapa detail pada imajinasi.)

Terima kasih OP untuk pertanyaannya, dan TJ untuk jawabannya! Anda berdua sangat membantu. Kode tertanam di bawah ini sebagai cermin 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>


0

Berikut adalah kombinasi dari dua persyaratan: lacak posisi mouse, setiap 100 milidetik:

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

Ini melacak & bertindak pada posisi mouse, tetapi hanya setiap periode milidetik.


0

Hanya versi sederhana dari jawaban @TJ Crowder dan @RegarBoy .

Kurang lebih menurut saya.

Lihat onmousemove event untuk info lebih lanjut tentang acara tersebut.

Pelacak mouse gambar

Ada nilai baru posXdan posYsetiap kali mouse bergerak sesuai dengan koordinat horizontal dan vertikal.

<!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>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.