Javascript - Theo dõi vị trí chuột


160

Tôi hy vọng theo dõi vị trí của con trỏ chuột, định kỳ mỗi t ms giây. Vì vậy, về cơ bản, khi tải trang - trình theo dõi này sẽ bắt đầu và cứ sau 100 ms, tôi sẽ nhận được giá trị mới của posX và posY và in nó ra dưới dạng.

Tôi đã thử đoạn mã sau - nhưng các giá trị không được làm mới - chỉ các giá trị ban đầu của posX và posY hiển thị trong các hộp mẫu. Bất cứ ý tưởng về làm thế nào tôi có thể có được điều này và chạy?

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

Vấn đề là sẽ không có eventđối tượng khi hàm được gọi lần thứ hai. Bạn có thể nên nghe một số sự kiện hơn sử dụng setTimeout.
Felix Kling

Có, nhưng không nên hàm mouse_poseition () cứ tự gọi sau mỗi 100 mili giây. Nó không thực sự hoạt động như một hàm đệ quy vô hạn?
Hari


@Titan: Có, nhưng tôi nghi ngờ rằng nó sẽ bị lỗi vì window.eventsẽ undefinedhoặc null. Nếu không có sự kiện, không có eventđối tượng.
Felix Kling

1
Không quan tâm, ứng dụng này là gì?
SuperUberDuper

Câu trả lời:


178

Vị trí của chuột được báo cáo về eventđối tượng mà người xử lý nhận được cho mousemovesự kiện mà bạn có thể đính kèm vào cửa sổ (bong bóng sự kiện):

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

(Lưu ý rằng phần thân của nó ifsẽ chỉ chạy trên IE cũ.)

Ví dụ về hành động trên - nó vẽ các dấu chấm khi bạn kéo chuột trên trang. (Đã thử nghiệm trên IE8, IE11, Firefox 30, Chrome 38.)

Nếu bạn thực sự cần một giải pháp dựa trên bộ đếm thời gian, bạn kết hợp điều này với một số biến trạng thái:

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

Theo như tôi biết, bạn không thể có được vị trí chuột mà không thấy sự kiện, điều mà câu trả lời này cho câu hỏi Stack Overflow khác dường như xác nhận.

Lưu ý bên lề : Nếu bạn sẽ làm một cái gì đó cứ sau 100ms (10 lần / giây), hãy cố gắng giữ quá trình xử lý thực tế bạn làm trong chức năng đó rất, rất hạn chế . Đó là rất nhiều công việc cho trình duyệt, đặc biệt là những trình duyệt cũ của Microsoft. Vâng, trên các máy tính hiện đại có vẻ không nhiều, nhưng có rất nhiều thứ đang diễn ra trong các trình duyệt ... Vì vậy, ví dụ, bạn có thể theo dõi vị trí cuối cùng bạn đã xử lý và bảo lãnh ngay lập tức nếu vị trí đó không xảy ra ' t thay đổi.


66

Đây là một giải pháp, dựa trên jQuery và trình nghe sự kiện chuột (tốt hơn nhiều so với bỏ phiếu thông thường) trên cơ thể:

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

Như tôi đã đề cập, việc bỏ phiếu thường xuyên là chính xác những gì tôi muốn làm. Tôi không theo dõi các thay đổi trong các sự kiện chuột, tôi chỉ tìm cách nắm bắt vị trí chuột mỗi x mili giây (không phân biệt chuột có di chuyển hay không).
Hari

3
Tại sao theo dõi một giá trị mà bạn biết chắc chắn không thay đổi? Tôi không hiểu, trừ khi đó là một vấn đề bài tập về nhà. Với phương thức sự kiện, bạn có thể theo dõi mọi thay đổi của các giá trị này, sau đó thực hiện bỏ phiếu 100ms ở nơi khác nếu bạn cần xử lý các giá trị này cho bất kỳ mục đích nào.
solendil

1
Không có lợi thế khi sử dụng jQuery ở đây ngoại trừ việc sử dụng lib lib 5mb không cần thiết
Pattydding Jr

@PattyddingJr Lần cuối cùng tôi nhìn nó là dưới 90kB trong phiên bản rút gọn
Kris

1
@PattycakeJr cũng nếu bạn siêu tải nó khó xảy ra ở tất cả nếu bạn trỏ đến một CDN kể từ khi hầu hết các liên kết trang web khác để nó
Brian Leishman

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

Mở bảng điều khiển của bạn ( Ctrl+ Shift+ J), sao chép-dán mã ở trên và di chuyển chuột trên cửa sổ trình duyệt.


1
Imo câu trả lời hay nhất
Dưới đây là

10

Tôi tin rằng chúng ta đang xem xét lại điều này,

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


1
Tôi mới tham gia diễn đàn này, vì vậy để tôi biết, xin vui lòng giải thích lý do tại sao bạn là người nhận thức của tôi - điều này là để tôi không mắc lại sai lầm tương tự. Cảm ơn! ThePROgrammer
dGRAMOP

10
Tôi cũng cảm thấy khó chịu bởi downvote không có lời giải thích. Để cung cấp cho bạn một lời giải thích có thể, câu trả lời này không giải quyết vấn đề bỏ phiếu của OP cứ sau 100 ms. Rõ ràng hơn trong phản ứng của ông đối với các câu trả lời khác rằng đây là một điều cần thiết.
aaaaaa

1
Tôi tin rằng loại xử lý sự kiện nội tuyến này không được chấp nhận. document.body.addEventListener("mousemove", function (e) {})là cách để làm điều này, trong mã javascript của bạn trái ngược với html
Ryan

10

Điều tôi nghĩ rằng anh ta chỉ muốn biết vị trí con trỏ X / Y hơn là tại sao câu trả lời lại phức tạp đến vậ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

Mã dựa trên ES6:

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

document.addEventListener('mousemove', handleMousemove);

Nếu bạn cần điều chỉnh cho mousemoving, hãy sử dụng:

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

đây là ví dụ


2

Không phân biệt trình duyệt, các dòng bên dưới hoạt động để tôi tìm nạp vị trí chuột chính xác.

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


2

Nếu chỉ muốn theo dõi chuyển động chuột một cách trực quan:

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

Tôi không có đủ danh tiếng để gửi trả lời nhận xét, nhưng đã lấy câu trả lời xuất sắc của TJ Crowder và xác định đầy đủ mã trên đồng hồ bấm giờ 100ms . (Anh ấy để lại một số chi tiết cho trí tưởng tượng.)

Cảm ơn OP cho câu hỏi và TJ cho câu trả lời! Cả hai bạn đều là một trợ giúp tuyệt vời. Mã được nhúng bên dưới như một tấm gương của 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

Đây là sự kết hợp của hai yêu cầu: theo dõi vị trí chuột, cứ sau 100 mili giây:

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

Điều này theo dõi & hành động trên vị trí chuột, nhưng chỉ mỗi chu kỳ mili giây.


0

Chỉ là một phiên bản đơn giản của câu trả lời của @TJ Crowder@RegarBoy .

Ít hơn là theo ý kiến ​​của tôi.

Kiểm tra sự kiện onmousemove để biết thêm thông tin về sự kiện này.

Theo dõi chuột hình ảnh

Có một giá trị mới posXposYmỗi khi chuột di chuyển theo tọa độ ngang và dọc.

<!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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.