자바 스크립트에서 마우스 포인터가 위에있는 요소를 확인합니다.


110

마우스 커서가 어떤 요소 위에 있는지 알려주는 함수를 원합니다.

예를 들어, 사용자의 마우스가이 텍스트 영역 (id 포함 wmd-input) 위에 있으면 호출 window.which_element_is_the_mouse_on()은 기능적으로 다음과 같습니다.$("#wmd-input")

답변:


148

데모

document.elementFromPoint소리를내는 정말 멋진 함수 가 있습니다.

우리에게 필요한 것은 마우스의 x와 y 좌표를 찾아서 그 값을 사용하여 호출하는 것입니다.

var x = event.clientX, y = event.clientY,
    elementMouseIsOver = document.elementFromPoint(x, y);

document.elementFromPoint

jQuery 이벤트 객체


1
@TikhonJelvis : 여기 에서 IE와 파이어 폭스에서 지원된다는 것을 알았습니다. 이 두 가지를 얻으면 일반적으로 모두 얻습니다. MSDN MDN
qwertymk

1
대박. 이벤트를 잡지 않고 마우스의 좌표를 얻을 수있는 방법이 있습니까? (아마 내가 생각하지 않을 것입니다). 이것이 가능하지 않은 경우, 불행히도 나는이 방법보다 더 나은 생각하지 않는다 event.target또는 무엇 이건
톰 레먼

1
@HoraceLoeb 이벤트를 포착하지 않고는 마우스 좌표를 얻을 수 없습니다. 볼 이 SO 질문 추가 설명을위한
로건 Besecker

2
그것은 그것을하는 이상한 방법입니다. 이벤트를 잡았다면 왜 event.target?
pmrotule

3
답변이 무엇 event이고 어떻게 왔는지 설명하지 않습니다
vsync

64

최신 브라우저에서는 다음을 수행 할 수 있습니다.

document.querySelectorAll( ":hover" );

그러면 현재 문서 순서대로 마우스가 위에있는 항목의 NodeList가 제공됩니다. NodeList의 마지막 요소는 가장 구체적이며 앞의 각 요소는 부모, 조부모 등이어야합니다.


2
<li>다른 <li>요소 위에 잠시 드래그하는 동안 이것은 작동하지 않는 것 같습니다 .
Seiyria 2014-07-29

2
내가 가진 바이올린을 생성 $(':hover')하지만, 기본적으로 같은 일이 : jsfiddle.net/pmrotule/2pks4tf6
pmrotule

3
(function(){ var q = document.querySelectorAll(":hover"); return q[q.length-1]; })()
사용자

3
나는 이것의 성능이 끔찍하다고 느낍니다 .. 이것을 호출하면 mousemove성능이 저하 될 수 있습니다
vsync

49

다음은 실제로 질문에 대답하지 않을 수 있지만 이것은 인터넷 검색의 첫 번째 결과이기 때문에 (googler가 정확히 같은 질문을하지 않을 수도 있습니다.), 추가 입력을 제공하기를 바랍니다.

실제로 마우스가 현재 위에있는 모든 요소의 목록을 가져 오는 두 가지 방법이 있습니다 (최신 브라우저의 경우).

"구조적"접근 방식-오름차순 DOM 트리

dherman의 답변에서와 같이

var elements = document.querySelectorAll(':hover');

그러나 이것은 자식 만 조상을 오버레이한다고 가정합니다. 이는 일반적으로 일반적이지만 일반적으로 사실이 아닙니다. 특히 DOM 트리의 다른 분기에있는 요소가 서로 겹칠 수있는 SVG를 다룰 때 그렇습니다.

"시각적"접근 방식- "시각적"중첩 기반

이 방법은 document.elementFromPoint(x, y)최상위 요소를 찾고 일시적으로 숨기는 데 사용합니다 (동일한 컨텍스트에서 즉시 복구하므로 브라우저는 실제로이 요소를 렌더링하지 않습니다). 두 번째 최상위 요소를 찾습니다. 예를 들어 트리에 서로를 가리는 형제 요소가있을 때 예상 한 것을 반환합니다. 자세한 내용 은 이 게시물 을 참조하십시오.

function allElementsFromPoint(x, y) {
    var element, elements = [];
    var old_visibility = [];
    while (true) {
        element = document.elementFromPoint(x, y);
        if (!element || element === document.documentElement) {
            break;
        }
        elements.push(element);
        old_visibility.push(element.style.visibility);
        element.style.visibility = 'hidden'; // Temporarily hide the element (without changing the layout)
    }
    for (var k = 0; k < elements.length; k++) {
        elements[k].style.visibility = old_visibility[k];
    }
    elements.reverse();
    return elements;
}

둘 다 시도하고 서로 다른 수익을 확인하십시오.


이것은 나를 많이 도왔습니다. 감사합니다 @ herrlich10. 놀랍게도 코드는 중첩 된 자식 요소로 케이스를 처리합니다.
Vikram Deshmukh

이것은 매우 유용합니다. 내가 찾던 바로 그것. 말했듯이 querySelectorAll은 모든 시나리오에서 작동하지 않습니다.
noobsharp

4
@ herrlich10 이것은 developer.mozilla.org/en-US/docs/Web/API/Document/…에 대한 괜찮은 polyfill처럼 보입니다 . 해당 API가 지원되는 browserSet에 있으면 사용할 수 있다고 생각합니다.
dherman

이것에 대해 감사합니다-expetced (getElementsFromPoint와의 호환성을 위해 elements.reverse가 없지만)만큼 느리게 작동하지만 (크롬 테스트에서 호출 당 18-20ms) 내가 가진 시나리오에서 사용하기가 어렵습니다. 마음 (보다 기본적인 이벤트 중심 접근 방식을 사용할 수없는 경우 드래그하는 동안 드롭 대상 찾기).
jsdw

1
참조 Document.elementsFromPoint(x, y) stackoverflow.com/a/31805883/1059828
칼 애들러

21

elementFromPoint()DOM 트리의 첫 번째 요소 만 가져옵니다. 이것은 대부분 개발자의 요구에 충분하지 않습니다. 예를 들어 현재 마우스 포인터 위치에서 둘 이상의 요소를 얻으려면 다음이 필요한 함수입니다.

document.elementsFromPoint(x, y) . // mind the 's' in elements

이것은 주어진 지점 아래의 모든 요소 객체의 배열을 반환합니다. 이 함수에 마우스 X 및 Y 값을 전달하기 만하면됩니다.

자세한 정보 : https://developer.mozilla.org/en-US/docs/Web/API/document/elementsFromPoint

지원되지 않는 아주 오래된 브라우저의 경우이 답변 을 대체 수단으로 사용할 수 있습니다 .


3
이제 2018 년에 잘 지원됩니다.
Boy

6

당신이 몸에 하나의 수신기를 넣고 거품이 최대로 기다릴 수 있도록 마우스 오버 이벤트 거품, 다음 잡아 event.target또는 event.srcElement:

function getTarget(event) {
    var el = event.target || event.srcElement;
    return el.nodeType == 1? el : el.parentNode;
}

<body onmouseover="doSomething(getTarget(event));">

내가 범용 이벤트 핸들러를 사용하는 동안 이것은 document.elementFromPoint(x, y).

6

다음 코드는 마우스 포인터 요소를 가져 오는 데 도움이됩니다. 결과 요소가 콘솔에 표시됩니다.

document.addEventListener('mousemove', function(e) {
    console.log(document.elementFromPoint(e.pageX, e.pageY)); 
})

1
이동하려면 커서가 필요합니다. 가능한 한 가깝게 여기에서 요청하는 것이 아닙니다.
Carles Alcolea

페이지를 스크롤하면 작동하지 않습니다. 대신 e.clientX및 사용하십시오 e.clientY(Firefox 59에서 테스트 됨).
youen 2018 년

5

mouseover적절한 조상 에서 이벤트 의 대상을 볼 수 있습니다 .

var currentElement = null;

document.addEventListener('mouseover', function (e) {
    currentElement = e.target;
});

여기 데모가 있습니다.


4
<!-- One simple solution to your problem could be like this: -->

<div>
<input type="text" id="fname" onmousemove="javascript: alert(this.id);" />
<!-- OR -->
<input type="text" id="fname" onclick="javascript: alert(this.id);" />
</div>
<!-- Both mousemove over the field & click on the field displays "fname"-->
<!-- Works fantastic in IE, FireFox, Chrome, Opera. -->
<!-- I didn't test it for Safari. -->

3
귀하의 (현재 삭제 된) 질문에 대해 귀하가 처한 방식에 대해 사과드립니다. 개인적으로 질문이 삭제 취소되는 것을 선호합니다. 문을 닫는 도중에 (부당하게 제 생각에는) 다시 문을 열도록 투표 할 계획이었습니다. 그러나 반대 투표 수를 고려할 때 삭제 유지를 선택하면 이해합니다.
하프 러

3

데모 : D 스 니펫 창에서 마우스를 이동합니다. : D

<script>
document.addEventListener('mouseover', function (e) {
	  console.log ("You are in ",e.target.tagName);
});
</script>


1

mousemoveDOM 이벤트 의 대상은 마우스가 움직일 때 커서 아래에있는 최상위 DOM 요소입니다.

(function(){
    //Don't fire multiple times in a row for the same element
    var prevTarget=null;
    document.addEventListener('mousemove', function(e) {
        //This will be the top-most DOM element under cursor
        var target=e.target;
        if(target!==prevTarget){
            console.log(target);
            prevTarget=target;
        }
    });
})();

이것은 @Philip Walton의 솔루션과 유사하지만 jQuery 또는 setInterval이 필요하지 않습니다.


1

이 선택기를 사용하여 개체를 undermouse하고 jquery 개체로 조작 할 수 있습니다. $(':hover').last();


4
Stack Overflow에 오신 것을 환영합니다! 이 코드가 OP에 도움이되는 이유에 대한 설명을 추가하십시오. 이는 향후 시청자가 배울 수있는 답을 제공하는 데 도움이 될 것입니다. 자세한 내용 은 응답 방법을 참조하십시오 . 또한 "언더 마우스"?
Heretic Monkey

0

제가 제안하려는 방법을 사용하지 않는 것이 좋습니다. 그것은 단지 당신이 마우스로 이상 여부를 알고 관심있는 요소를 사용하여 이벤트 기반의 개발 및 바인드 이벤트에 훨씬 더 나은 mouseover, mouseout, mouseenter,mouseleave , 등

마우스가 어떤 요소 위에 있는지 알 수있는 능력이 절대적으로 있어야한다면, 바인딩하는 함수를 작성해야합니다. mouseover 이벤트를 DOM의 모든 것에 하고 현재 요소가 어떤 변수에 있든 저장해야합니다.

다음과 같이 할 수 있습니다.

window.which_element_is_the_mouse_on = (function() {

    var currentElement;

    $("body *").on('mouseover', function(e) {
        if(e.target === e.currentTarget) {
            currentElement = this;
        }
    });

    return function() {
        console.log(currentElement);    
    }
}());

기본적으로 모든 요소에 이벤트를 설정하고 현재 요소를 클로저 내에 저장하여 풋 프린트를 최소화하는 즉각적인 함수를 만들었습니다.

다음은 window.which_element_is_the_mouse_on매초 호출 하고 현재 마우스가 콘솔에있는 요소를 기록 하는 작업 데모입니다 .

http://jsfiddle.net/LWFpJ/1/


0

오래된 질문이지만 여전히 어려움을 겪고있는 사람들을위한 해결책이 있습니다. mouseover감지하려는 하위 요소의 '부모'요소에 이벤트 를 추가하려고합니다 . 아래 코드는 이에 대한 방법을 보여줍니다.

const wrapper = document.getElementById('wrapper') //parent element
const position = document.getElementById("displaySelection")

wrapper.addEventListener('mousemove', function(e) {
  let elementPointed = document.elementFromPoint(e.clientX, e.clientY)

  console.log(elementPointed)
});

코덱 데모

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