이벤트없이 마우스 위치를 얻는 방법 (마우스를 움직이지 않고)?


286

마우스를 움직이지 않고 마우스 이동 이벤트없이 페이지로드 후 JavaScript로 마우스 위치를 가져올 수 있습니까?


61
mousemove 이벤트에 문제가 없습니다. 경우에 따라 사용자는 마우스를 움직이지 않습니다. 답변 주셔서 감사합니다.
Norbert Tamas

2
@SuperNova의 답변 인 Norbert Tamas (올해까지 추가되지 않았 음)는 마우스가 페이지로드시 (마우스가 뷰포트에있는 경우) 실행되므로 마우스 입력기가 제대로 작동 함을 보여줍니다. 2010 년에 그런 식으로 작동하지 않았습니까? 아니면 아무도 그것을 시도하지 않았다고 생각합니까?
피터 한센

@CrescentFresh 경우에 따라 (사용자 스크립트와 같은) 많은 mousemove이벤트 를 추가하여 브라우저 속도를 낮추고 싶지 않습니다 .
Tomáš Zato-복원 모니카

마우스 오버로 FF에서 가능하지만 IE 및 Chrome에는 없습니다.
Elad

또는 게임에서 카메라가 게임 세계를 돌아 다니며 캐릭터가 마우스 (일반적인 하향식 사수 스타일)를보고 있지만 사용자가 마우스를 움직이지 않으면 이동시 잘못된 지점을 중심으로합니다. 당신은 mousemove에만 의존합니다. 그러나 큰 문제는 아니며 포인터의 "세계"좌표를 저장하고 사람들이 쿼리하도록합니다.
kamranicus

답변:


336

실제 답변 : 아니요, 불가능합니다.

좋아, 방금 방법을 생각했다. 전체 문서를 다루는 div로 페이지를 오버레이하십시오. 그 안에 2,000 x 2,000 개의 <a>요소 ( :hover가상 클래스가 IE 6에서 작동하도록 참조하십시오)의 크기는 각각 1 픽셀입니다. 속성을 변경하는 요소에 :hover대한 CSS 규칙을 작성하십시오 <a>(말하자 font-family). 로드 핸들러에서 4 백만 개 <a>요소 각각을 순환 하면서 마우스로 글꼴이있는 요소 를 찾을 때까지 currentStyle/를 확인 getComputedStyle()하십시오. 이 요소에서 다시 추정하여 문서 내의 좌표를 가져옵니다.

NB는 이 작업을 수행하지 마십시오 .


92
하하-어떤 시점에서 당신은 구글 주위에 실제로 얼마나 많은 사람들이 이것을 구현했는지 알아낼 수 있는지 확인
Pointy

6
실제로, 그것은 많은 CPU로드를 필요로하지 않고 구현 가능합니다 (제 생각에는 테스트하지 않았습니다). dom ready 자바 스크립트로 <a> 요소를 빌드하고 마우스 위치를 잡고 모든 <a> 요소를 제거하십시오. 마우스 마우스에서는 마우스 위치를 잡는 다른 기능이 있어야합니다. 어쨌든 이것은 재미있었습니다.
machineaddict

21
아마도 이것은 바이너리 검색으로 실용적이 될 수 있습니까? <a>주어진 사각형을 덮는 한 쌍의 요소를 루프로 만들고 (크기가 지정된 요소의 절대 위치 지정을 사용하여 <img>) 매번 사각형을 축소합니다. 예, 우스운 일이지만 첫 번째 mousemove 전에이 정보를 얻을 수 없습니다.
다리우스 베이컨

29
stackoverflow.com/a/8543879/27024에 따르면 마우스가 처음 움직일 때까지 호버가 시작되지 않습니다. 이것은이 계획을 망칩니다.
다리우스 베이컨

4
@DariusBacon : 그 연결된 대답이 정확하지 않은 것 같습니다 : jsbin.com/utocax/3 . 따라서이 방법은 일부 상황에서 실용적 일 수 있습니다.
Tim Down

121

편집 2020 : 더 이상 작동 하지 않습니다 . 브라우저 공급 업체가 이것을 패치 한 것처럼 보입니다. 대부분의 브라우저는 크롬에 의존하기 때문에 핵심 일 수 있습니다.

이전 답변 : mouseenter를 연결할 수도 있습니다 (이 이벤트는 마우스 커서가 페이지 안에있을 때 페이지를 다시로드 한 후에 시작됩니다). Corrupted의 코드를 확장하면 트릭을 수행해야합니다.

var x = null;
var y = null;
    
document.addEventListener('mousemove', onMouseUpdate, false);
document.addEventListener('mouseenter', onMouseUpdate, false);
    
function onMouseUpdate(e) {
  x = e.pageX;
  y = e.pageY;
  console.log(x, y);
}

function getMouseX() {
  return x;
}

function getMouseY() {
  return y;
}

mouseleave-event에서 x와 y를 null로 설정할 수도 있습니다. 따라서 사용자가 커서로 페이지에 있는지 확인할 수 있습니다.


11
이것은 여기서 유일하게 유용한 유용한 답변 인 것 같습니다. 실제로 (최신 Firefox, Chrome 및 IE11에서) 마우스 입력기는 페이지로드시 실행되고 올바른 좌표를 제공합니다. 이 분야의 브라우저 동작이 지난 몇 년 동안 단순히 바뀌 었습니까?
피터 한센

3
사실 "mouseenter"는 어떤 가치도 부가하지 않는 것 같습니다. Chrome 및 IE에서 다음 jsfiddle로 테스트했으며 내부 문서 (결과 패널)에 마우스를 놓을 때까지 좌표가 표시되지 않습니다. jsfiddle.net/xkpd784o/1
Mariano Desanze

1
@Proton : 페이지가 완전히로드되어 움직이지 않고 결과 패널 영역으로 마우스를 결과 패널로 이동하십시오. 페이지를 온로드하면 즉시 마우스의 위치를 ​​알게됩니다. 마우스 움직임이 필요하지 않습니다. 따라서 페이지가로드되고 마우스가 문서 영역 안에 있으면 mouseenter도 실행됩니다. 즉, OP가 원했던 것입니다. 아무도이 답변을 제공하지 않습니다.
SuperNova

1
잠재적으로 유용한 부가가하는 기능을 추가하는 mouseleave세트 해당 이벤트 xy다시 null또는'undefined'
rtpax

2
위의 jsfiddel을 사용하는 크롬 68은 페이지 로딩이 완료되기 전에 마우스가 렌더링 된 영역으로 이동하더라도로드 시가 아니라 첫 번째 마우스 이동시 경고가 발생합니다.
junvar

84

당신이 할 수있는 무엇인가가에 대한 변수 생성 xy커서의 좌표를, 그들을 업데이트 할 때마다 마우스를 이동하고 저장 위치에 무엇을해야하는 구간에서 함수를 호출합니다.

물론 이것의 단점은 마우스가 작동하기 위해서는 최소한 한 번의 초기 움직임이 필요하다는 것입니다. 커서가 한 번 이상 위치를 업데이트하는 한, 다시 이동하는지 여부에 관계없이 위치를 찾을 수 있습니다.

var cursorX;
var cursorY;
document.onmousemove = function(e){
    cursorX = e.pageX;
    cursorY = e.pageY;
}
setInterval(checkCursor, 1000);
function checkCursor(){
    alert("Cursor at: " + cursorX + ", " + cursorY);
}

앞의 코드는 커서 위치에 대한 메시지로 1 초에 한 번 업데이트됩니다. 이게 도움이 되길 바란다.


18
이 게시물의 주제를 읽었습니까? OP는 이벤트를 사용하지 않고 마우스 좌표를 얻는 방법을 묻습니다. 그러나 귀하의 게시물은 onmousemove 이벤트 사용을 제안합니다.
jake

53
@jake OP가 이벤트가 아닌 방법을 구체적으로 요청했지만이 답변은 여기에 와서 답변과 해결 방법을 찾는 다른 사람들에게 도움이됩니다. 또한 내가 아는 한이 답변을 주제 내에서 부분적으로 고려할 것입니다. 이벤트를 직접 사용하지 않고도 주어진 시간에 커서 위치를 얻는 가장 좋은 방법입니다. 즉, 사실을 진술하고 주석에서 nitpicking을 피할 수있는 방법을 제공하는 선을 따라 대답이 더 많이 표현 될 수 있습니다.
jpeltoniemi

2
@ Pichan cursorX/Y이벤트가 발생하기 전에 변수 를 채울 수있는 방법을 찾고 있었기 때문에 이점이 없었습니다 .
polkovnikov.ph

아주 소수의 사용자 습관 화재 마우스 이벤트
SuperUberDuper

1
조심스럽게 mousemove 리스너를 유지하는 데 비용이 많이들 수 있습니다. 간격을두고 리스너를 다시 만들고 좌표를 얻은 후 리스너를 제거하는 것이 좋습니다.
KRB

10

Tim Down이 제안한 것과 비슷한 것을 시도해 볼 수 있습니다.하지만 화면에 각 픽셀마다 요소를 두는 대신 2-4 개의 요소 (상자) 만 만들고 위치, 너비, 높이를 동적으로 변경하여 화면에서 아직 가능한 위치를 나눕니다. 재귀 적으로 2-4까지함으로써 마우스의 실제 위치를 빠르게 찾을 수 있습니다.

예를 들어, 첫 번째 요소는 화면의 오른쪽과 왼쪽 절반을 차지하고 그 다음에 위쪽과 아래쪽 절반을 가져옵니다. 지금까지 우리는 이미 마우스의 4 분의 1의 스크린 위치를 알고 반복 할 수 있습니다.이 공간의 4 분의 1을 발견하십시오.


9

2,000 x 2,000 <a>요소 를 렌더링하면 @Tim Down의 대답이 성능이 좋지 않습니다 .

좋아, 방금 방법을 생각했다. 전체 문서를 다루는 div로 페이지를 오버레이하십시오. 그 안에 2,000 x 2,000 개의 요소를 만듭니다 (예 : : 호버 의사 클래스는 IE 6에서 작동합니다 참조). 각 1 픽셀 크기. 속성을 변경하는 요소 (font-family)에 대해 CSS : hover 규칙을 만듭니다. 로드 핸들러에서 4 백만 요소 각각을 순환하면서 호버 글꼴이있는 요소를 찾을 때까지 currentStyle / getComputedStyle ()을 확인하십시오. 이 요소에서 다시 추정하여 문서 내의 좌표를 얻습니다.

NB는 이것을하지 마십시오.

그러나 한 번에 4 백만 개의 요소를 렌더링 할 필요는 없으며 대신 이진 검색을 사용하십시오. <a>대신 4 개의 요소를 사용하십시오.

  • 1 단계 : 전체 화면을 시작 검색 영역으로 간주
  • 2 단계 : 검색 영역을 2 x 2 = 4 개의 사각형 <a>요소 로 분할
  • 3 단계 : getComputedStyle()함수를 사용하여 사각형 마우스 호버를 결정
  • 4 단계 : 검색 영역을 해당 사각형으로 줄이고 2 단계부터 반복하십시오.

이렇게하면 화면이 2048px보다 넓지 않다는 것을 고려 하여이 단계를 최대 11 번 반복해야합니다.

따라서 최대 11 x 4 = 44 <a>요소를 생성 합니다.

마우스 위치를 정확히 픽셀로 결정할 필요는 없지만 10px 정밀도는 괜찮습니다. 최대 8 번 단계를 반복하므로 최대 8 x 4 = 32 개의 <a>요소 를 그려야 합니다.

<a>DOM이 일반적으로 느리기 때문에 요소 를 생성하고 파괴하는 것은 수행되지 않습니다. 대신, 당신은 단지 초기 4 개 다시 사용할 수있는 <a>요소와 그들의 조정 top, left, widthheight단계를 같은 루프를.

이제 4를 만드는 <a>것도 과잉입니다. 대신 각 사각형에서 <a>테스트 할 때 동일한 요소 하나를 재사용 할 수 있습니다 getComputedStyle(). 따라서 검색 영역을 2 x 2 <a>요소 로 분할하는 대신 단일 <a>요소를 이동 top하고 left스타일 속성을 사용 하여 단일 요소를 재사용하면 됩니다.

그래서, 당신이 필요 하나입니다 <a>요소의 변경 widthheight최대 11 시간을, 그 변경 topleft최대 44 시간을 당신이 정확한 마우스 위치를해야합니다.


3

가장 간단한 솔루션이지만 100 % 정확하지는 않습니다.

$(':hover').last().offset()

결과 : {top: 148, left: 62.5}
결과는 가장 가까운 요소 크기에 따라 달라지며 undefined사용자가 탭을 전환했을 때 반환 됩니다.


나를 위해, 그것은 undefined상관없이 돌아갑니다 . 이것을 사용하는 방법을 자세히 설명해 주시겠습니까?
tresf

undefined커서가 요소를 가리 키지 않았을 때 (또는 브라우저가 포커스를 잃었을 때) 반환 됩니다. 콘솔에서 테스트하는 경우 시간 간격을 설정해야 할 수도 있습니다.
StefansArya

감사. setTimeout일했다. 나는 jsfiddle을 사용하고 있었고 당신이 옳았습니다. 플레이를 클릭 할 때마다 DOM을 다시 그리기 때문에 호버 이벤트가 발생하지 않았습니다. 이 힌트를 다른 사람들에게 추가하는 것이 좋습니다.
tresf

나는 정확한 마우스 위치를 원하지 않지만 마우스가 이벤트 객체없이 기능에 극도로 오른쪽 또는 극도로 남아 있다는 것을 알고 싶습니다. 그래서 솔루션이 제 경우에 작동합니다. 감사합니다
Swap-IOS-Android

2

타이머가있는 부모 페이지가 있고 일정 시간이나 작업이 완료되면 사용자를 새 페이지로 전달합니다. 이제 커서 위치를 원하고 기다리고 있기 때문에 반드시 마우스에 닿아있을 필요는 없습니다. 따라서 표준 이벤트를 사용하여 상위 페이지에서 마우스를 추적하고 get 또는 post 변수에서 마지막 값을 새 페이지에 전달하십시오.

부모님 페이지에서 JHarding의 코드를 사용하면 항상 전역 변수에서 최신 위치를 사용할 수 있습니다.

var cursorX;
var cursorY;
document.onmousemove = function(e){
    cursorX = e.pageX;
    cursorY = e.pageY;
}

부모 페이지 이외의 방법으로이 페이지를 탐색하는 사용자에게는 도움이되지 않습니다.


1

위의 Tim Down의 아이디어와 같이 수평 / 수직 검색을 구현했습니다 (먼저 가로로 정렬 된 세로선 링크로 div를 가득 채우고 세로로 정렬 된 가로선 링크로 div를 가득 채우고 어떤 것이 호버 상태인지 확인하십시오). 꽤 빨리 작동합니다. 안타깝게도 KDE의 Chrome 32에서는 작동하지 않습니다.

jsfiddle.net/5XzeE/4/


사용자가 명시 적으로 마우스를 움직이지 않으면 이러한 트릭은 더 이상 작동하지 않습니다. :(
trusktr

1

커서의 위치를 ​​얻기 위해 마우스 를 움직일 필요는 없습니다 . 위치는 mousemove 이외의 이벤트에서도보고됩니다 . 클릭 이벤트 는 다음과 같습니다 .

document.body.addEventListener('click',function(e)
{
    console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});

1

@SuperNova 의 답변 을 인용하면 this다음은 콜백에서 컨텍스트를 올바르게 유지하는 ES6 클래스를 사용하는 접근 방식입니다 .

class Mouse {
  constructor() {
    this.x = 0;
    this.y = 0;
    this.callbacks = {
      mouseenter: [],
      mousemove: [],
    };
  }

  get xPos() {
    return this.x;
  }

  get yPos() {
    return this.y;
  }

  get position() {
    return `${this.x},${this.y}`;
  }

  addListener(type, callback) {
    document.addEventListener(type, this); // Pass `this` as the second arg to keep the context correct
    this.callbacks[type].push(callback);
  }

  // `handleEvent` is part of the browser's `EventListener` API.
  // https://developer.mozilla.org/en-US/docs/Web/API/EventListener/handleEvent
  handleEvent(event) {
    const isMousemove = event.type === 'mousemove';
    const isMouseenter = event.type === 'mouseenter';

    if (isMousemove || isMouseenter) {
      this.x = event.pageX;
      this.y = event.pageY;
    }

    this.callbacks[event.type].forEach((callback) => {
      callback();
    });
  }
}

const mouse = new Mouse();

mouse.addListener('mouseenter', () => console.log('mouseenter', mouse.position));
mouse.addListener('mousemove', () => console.log('mousemove A', mouse.position));
mouse.addListener('mousemove', () => console.log('mousemove B', mouse.position));


1

여기 내 해결책이 있습니다. 어디서나 사용할 수있는 window.currentMouseXwindow.currentMouseY 속성을 내 보냅니다 . 처음에 호버링 된 요소 (있는 경우)의 위치를 ​​사용하고 마우스 움직임을 듣고 올바른 값을 설정합니다.

(function () {
    window.currentMouseX = 0;
    window.currentMouseY = 0;

    // Guess the initial mouse position approximately if possible:
    var hoveredElement = document.querySelectorAll(':hover');
    hoveredElement = hoveredElement[hoveredElement.length - 1]; // Get the most specific hovered element

    if (hoveredElement != null) {
        var rect = hoveredElement.getBoundingClientRect();
        // Set the values from hovered element's position
        window.currentMouseX = window.scrollX + rect.x;
        window.currentMouseY = window.scrollY + rect.y;
    }

    // Listen for mouse movements to set the correct values
    document.addEventListener('mousemove', function (e) {
        window.currentMouseX = e.pageX;
        window.currentMouseY = e.pageY;
    });
}())

Composr CMS 소스 : https://github.com/ocproducts/composr/commit/a851c19f925be20bc16bfe016be42924989f262e#diff-b162dc9c35a97618a96748639ff41251R1202


0
var x = 0;
var y = 0;

document.addEventListener('mousemove', onMouseMove, false)

function onMouseMove(e){
    x = e.clientX;
    y = e.clientY;
}

function getMouseX() {
    return x;
}

function getMouseY() {
    return y;
}

14
그래도 사용자가 마우스를 움직여야합니까?
Paul Hiemstra

0

div와 픽셀 수를 계산하는 합리적인 솔루션이 있다고 생각합니다 ..lol

단순히 애니메이션 프레임이나 함수의 시간 간격을 사용하십시오. 마우스 이벤트를 시작하기 위해 한 번만 마우스 이벤트가 필요하지만 기술적으로 원하는 위치에 배치 할 수 있습니다.

본질적으로 우리는 마우스 움직임없이 항상 더미 div를 추적하고 있습니다.

// create a div(#mydiv) 1px by 1px set opacity to 0 & position:absolute;

아래는 논리입니다.

var x,y;


$('body').mousemove(function( e ) {

    var x = e.clientX - (window.innerWidth / 2);
    var y = e.clientY - (window.innerHeight / 2);
 }


function looping (){

   /* track my div position 60 x 60 seconds!
      with out the mouse after initiation you can still track the dummy div.x & y
      mouse doesn't need to move.*/

   $('#mydiv').x = x;    // css transform x and y to follow 
   $('#mydiv)'.y = y;

   console.log(#mydiv.x etc)

   requestAnimationFrame( looping , frame speed here);
}  
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.