Javascript - ติดตามตำแหน่งเม้าส์


161

ฉันหวังว่าจะติดตามตำแหน่งของเคอร์เซอร์ของเมาส์เป็นระยะ ๆ ทุก ๆ มิลลิวินาที ดังนั้นเมื่อหน้าโหลด - ตัวติดตามนี้ควรเริ่มต้นและสำหรับ (พูด) ทุก ๆ 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จะเป็นหรือundefined nullหากไม่มีเหตุการณ์แสดงว่าไม่มีeventวัตถุ
เฟลิกซ์คลิง

1
สิ่งที่เป็นประโยชน์ของแอพพลิเคชั่นนี้คืออะไร?
SuperUberDuper

คำตอบ:


178

ตำแหน่งของเมาส์ถูกรายงานบนeventวัตถุที่ได้รับโดยตัวจัดการสำหรับmousemoveเหตุการณ์ซึ่งคุณสามารถแนบกับหน้าต่าง (ฟองเหตุการณ์):

(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 เก่าเท่านั้น)

ตัวอย่างของการกระทำข้างต้น - มันจะวาดจุดเมื่อคุณลากเมาส์ไปวางบนหน้า (ทดสอบบน 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
        }
    }
})();

เท่าที่ฉันทราบคุณไม่สามารถรับตำแหน่งเมาส์โดยไม่ได้เห็นเหตุการณ์ซึ่งเป็นคำตอบสำหรับคำถาม Stack Overflow อื่นที่ดูเหมือนว่าจะยืนยัน

หมายเหตุด้านข้าง : หากคุณกำลังจะทำทุก ๆ 100ms (10 ครั้ง / วินาที) ให้พยายามประมวลผลที่แท้จริงที่คุณทำในฟังก์ชั่นนั้น จำกัด มากจำกัด นั่นเป็นงานจำนวนมากสำหรับเบราว์เซอร์โดยเฉพาะอย่างยิ่ง Microsoft ที่เก่ากว่า ใช่ในคอมพิวเตอร์สมัยใหม่ดูเหมือนว่าจะไม่มากนัก แต่มีเบราว์เซอร์เกิดขึ้นมากมาย ... ตัวอย่างเช่นคุณอาจติดตามตำแหน่งสุดท้ายที่คุณดำเนินการและประกันตัวจากผู้จัดการทันทีหากตำแหน่งมี ' เปลี่ยนไปแล้ว


66

นี่คือวิธีการแก้ปัญหาตาม jQuery และฟังเหตุการณ์เมาส์ (ซึ่งดีกว่าการเลือกตั้งทั่วไป) ในเนื้อหา:

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

ตามที่ได้กล่าวไปแล้วการลงคะแนนปกติเป็นสิ่งที่ฉันต้องการจะทำ ฉันไม่ได้ติดตามการเปลี่ยนแปลงในเหตุการณ์เมาส์ฉันแค่ค้นหาตำแหน่งเมาส์ทุก ๆ สิบมิลลิวินาที (ไม่ว่าเมาส์จะขยับหรือไม่ก็ตาม)
Hari

3
เหตุใดการติดตามค่าที่คุณรู้ว่าไม่เปลี่ยนแปลง ฉันไม่เข้าใจเว้นแต่จะเป็นปัญหาการบ้าน ด้วยวิธีการเหตุการณ์คุณสามารถติดตามการเปลี่ยนแปลงค่าเหล่านี้ทุกครั้งจากนั้นทำการสำรวจ 100ms ที่อื่นถ้าคุณต้องการจัดการค่าเหล่านี้เพื่อจุดประสงค์ใดก็ตาม
Solendil

1
มีไม่ประโยชน์ของการใช้ jQuery ที่นี่ยกเว้นไม่จำเป็นใช้ 5MB JS lib
Pattycake จูเนียร์

@PattycakeJr ครั้งสุดท้ายที่ฉันดูมันต่ำกว่า 90kB ในเวอร์ชั่นย่อ
Kris

1
@PattycakeJr เช่นกันถ้าคุณไม่ได้ดาวน์โหลดมันสุดยอดเลยถ้าคุณชี้ไปที่ CDN เพราะเกือบทุกเว็บไซต์อื่นลิงก์ไปถึงมัน
Brian Leishman

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

เปิดคอนโซลของคุณ ( Ctrl+ Shift+ J) คัดลอกวางโค้ดด้านบนและเลื่อนเมาส์ไปที่หน้าต่างเบราว์เซอร์


1
Imo คำตอบที่ดีที่สุด
นี่

10

ฉันเชื่อว่าเราคิดมากเรื่องนี้

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


1
ฉันใหม่กับฟอรัมนี้ดังนั้นเพื่อให้ฉันรู้โปรดอธิบายว่าทำไมคุณ -1nd awnser ของฉัน - นี่คือดังนั้นฉันไม่ทำผิดพลาดอีกครั้ง ขอบคุณ! ThePROgrammer
dGRAMOP

10
ฉันก็รู้สึกหงุดหงิดด้วย downvotes โดยไม่มีคำอธิบาย เพื่อให้คำอธิบายที่เป็นไปได้คำตอบนี้ไม่ได้แก้ปัญหาการลงคะแนนเลือกตั้งของ OP ทุก ๆ 100 มิลลิวินาที ชัดเจนในการตอบสนองต่อคำตอบอื่น ๆ ของเขาว่านี่เป็นสิ่งจำเป็น
aaaaaa

1
ฉันเชื่อว่าการจัดการเหตุการณ์แบบอินไลน์เช่นนี้ document.body.addEventListener("mousemove", function (e) {})เป็นวิธีที่จะทำเช่นนี้ในโค้ดจาวาสคริปต์ของคุณเมื่อเทียบกับใน HTML
ไรอัน

10

สิ่งที่ฉันคิดว่าเขาต้องการเพียงแค่รู้ตำแหน่งของเคอร์เซอร์ 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>


5

รหัส 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));

นี่คือตัวอย่าง


2

โดยไม่คำนึงถึงเบราว์เซอร์บรรทัดด้านล่างทำงานให้ฉันเพื่อดึงตำแหน่งเมาส์ที่ถูกต้อง

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


2

หากต้องการติดตามการเคลื่อนไหวของเมาส์ด้วยสายตา:

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

ฉันไม่ได้มีชื่อเสียงพอที่จะแสดงความคิดเห็นตอบกลับ แต่เอา TJ Crowder ของคำตอบที่ดีเยี่ยมและการกำหนดไว้อย่างเต็มที่รหัสในการจับเวลา 100ms (เขาทิ้งรายละเอียดบางอย่างไว้ในจินตนาการ)

ขอบคุณ 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>


0

นี่คือการรวมกันของข้อกำหนดสองข้อ: ติดตามตำแหน่งเมาส์ทุกๆ 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);
}

แทร็กนี้จะทำงานตามตำแหน่งของเมาส์ แต่จะมีระยะเวลาเป็นมิลลิวินาทีทุกวินาที


0

เพียงแค่รุ่นที่เรียบง่ายของ@TJ Crowderและคำตอบของ@RegarBoy

ความคิดเห็นของฉันมีน้อยมาก

ตรวจสอบกิจกรรม onmousemoveสำหรับข้อมูลเพิ่มเติมเกี่ยวกับเหตุการณ์

ติดตามเมาส์ภาพ

มีค่าใหม่posXและposYทุกครั้งที่เมาส์เลื่อนตามพิกัดแนวนอนและแนวตั้ง

<!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>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.