자바 스크립트-마우스 위치 추적


161

마우스 커서의 위치를 ​​주기적으로 1m 초마다 추적하려고합니다. 따라서 본질적으로 페이지가로드 될 때-이 추적기는 시작하여 100ms마다 (예를 들어) 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함수가 두 번째로 호출 될 때 객체 가 없다는 것 입니다. 아마도 use보다 일부 이벤트를 들어야합니다 setTimeout.
— Felix Kling

예, 그러나 mouse_position () 함수가 100 밀리 초마다 계속 호출되지 않아야합니다. 실제로 무한 재귀 함수처럼 작동해서는 안됩니까?
— Hari


@Titan : 그렇습니다 . 또는로 인해 오류가 발생할 것으로 의심 window.event됩니다 . 이벤트가 없으면 오브젝트 가 없습니다 . undefinednullevent
— Felix Kling

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

내가 아는 한, 이벤트를 보지 않으면 마우스 위치를 얻을 수 없습니다. 다른 스택 오버플로 질문에 대한 대답 은 확인하는 것 같습니다.

참고 : 100ms (10 회 / 초)마다 무언가를 할 경우 해당 기능에서 수행하는 실제 처리를 매우 제한적으로 유지하십시오 . 브라우저, 특히 오래된 Microsoft 브라우저에서는 많은 작업이 필요합니다. 예, 최신 컴퓨터에서는별로 좋아 보이지 않지만 브라우저에는 많은 일이 발생합니다. 예를 들어, 처리 한 마지막 위치를 추적하고 해당 위치가 없을 경우 처리기에서 즉시 구제 할 수 있습니다. t가 변경되었습니다.


66

다음은 본문에서 jQuery 및 마우스 이벤트 리스너 (정기 폴링보다 훨씬 우수함)를 기반으로하는 솔루션입니다.

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

내가 언급했듯이, 정기적 인 폴링은 내가하고 싶은 일입니다. 마우스 이벤트의 변경 사항을 추적하지 않고 x 밀리 초마다 마우스 위치를 캡처하려고합니다 (마우스의 이동 여부에 관계없이).
— Hari

3
확실하게 알고있는 값을 추적해도 변경되지 않은 이유는 무엇입니까? 숙제 문제가 아닌 한 이해가되지 않습니다. 이벤트 방법을 사용하면 이러한 값의 모든 변경 사항을 추적 한 다음 목적에 관계없이 이러한 값을 처리해야하는 경우 다른 곳에서 100ms 폴링을 수행 할 수 있습니다.
— solendil

1
불필요하게 5mb JS 라이브러리를 사용하는 것을 제외하고 여기서 jQuery를 사용하는 이점은 없습니다
— Pattycake Jr

@PattycakeJr 내가 마지막으로 본 것은 축소 버전에서 90kB 미만이었습니다
— Kris

1
@PattycakeJr 당신이있어 또한 경우 최고 당신이 그것을 거의 다른 모든 사이트 링크 이후 CDN를 가리키는 경우 모두에서 다운로드를 가능성
— 브라이언 Leishman

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

콘솔 ( Ctrl+ Shift+ J)을 열고 위의 코드를 복사하여 붙여 넣은 다음 브라우저 창에서 마우스를 움직입니다.


1
최고의 답변 Imo
— HereHere

10

나는 우리가 이것을 지나치게 생각하고 있다고 믿습니다.

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


1
이 포럼을 처음 접했으므로 이유를 설명해주세요. 왜 -1 번째 내 차일-이것은 다시 같은 실수를하지 않기 위해서입니다. 감사! The PROgrammer
— dGRAMOP

10
나도 설명없이 downvotes에 의해 화가 나옵니다. 가능한 설명을 제공하기 위해이 답변은 100ms마다 폴링하는 OP의 문제를 해결하지 않습니다. 다른 답변에 대한 그의 대답에서 이것이 필요하다는 것이 더 분명합니다.
— aaaaaa

1
또한 이런 종류의 인라인 이벤트 처리는 더 이상 사용되지 않습니다. document.body.addEventListener("mousemove", function (e) {})html과 달리 자바 스크립트 코드에서이를 수행하는 방법입니다
— Ryan

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 크라우의 갔다하지 않는 훌륭한 답을 정의 완전하고 이 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.