development

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

big-blog 2020. 4. 2. 08:16
반응형

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


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


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

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

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


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로 설정할 수도 있습니다. 따라서 사용자가 커서로 페이지에 있는지 확인할 수 있습니다.


당신이 할 수있는 무엇인가가에 대한 변수 생성 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 초에 한 번 업데이트됩니다. 이게 도움이 되길 바란다.


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

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


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

좋아, 방금 방법을 생각했다. 전체 문서를 다루는 div로 페이지를 오버레이하십시오. 그 안에 2,000 x 2,000 개의 요소를 만듭니다 (예 : : hover 의사 클래스는 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 시간을 당신이 정확한 마우스 위치를해야합니다.


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

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

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


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

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

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

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


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

jsfiddle.net/5XzeE/4/


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

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

여기 내 해결책이 있습니다. 어디서나 사용할 수있는 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


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

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


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

참고 URL : https://stackoverflow.com/questions/2601097/how-to-get-the-mouse-position-without-events-without-moving-the-mouse

반응형