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


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 이벤트 를 확인하십시오 .

이미지 마우스 트래커

새로운 가치있다 posXposY때마다 가로, 세로 좌표에 따라 마우스 이동.

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