Pytanie Określ, który element wskaźnika myszy znajduje się na górze w JavaScript


Chcę funkcji, która mówi mi, który element kursor myszy się skończył.

Na przykład, jeśli mysz użytkownika znajduje się nad tym obszarem tekstowym (z identyfikatorem) wmd-input), dzwonienie window.which_element_is_the_mouse_on() będzie funkcjonalnie równoważny $("#wmd-input")


76
2018-01-11 01:32


pochodzenie




Odpowiedzi:


PRÓBNY

Jest naprawdę fajna funkcja document.elementFromPoint co robi, jak brzmi.

Potrzebujemy znaleźć współrzędne X i Y myszy, a następnie wywołać je za pomocą tych wartości:

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

document.elementFromPoint

Obiekt zdarzenia jQuery


105
2018-01-11 01:42



@TikhonJelvis: Cóż z tutaj Widzę, że jest obsługiwany na IE i Firefox. Jeśli zdobędziesz te dwie, zazwyczaj otrzymasz je wszystkie. MSDN  MDN - qwertymk
Niesamowite. Czy istnieje sposób, aby uzyskać współrzędne myszy BEZ złapania jakiegoś wydarzenia? (Prawdopodobnie nie zakładam). Jeśli nie jest to możliwe, to niestety nie sądzę, że ta metoda jest lepsza niż event.target lub cokolwiek - Tom Lehman
@HoraceLoeb Nie można uzyskać myszy ze współrzędnymi bez zauważenia zdarzenia. widzieć to pytanie SO dla dalszego wyjaśnienia - Logan Besecker
To dziwny sposób na zrobienie tego. Jeśli złapiesz wydarzenie, dlaczego nie po prostu użyć event.target ? - pmrotule
Odpowiedź nie wyjaśnia co event jest i jak do tego doszło - vsync


W nowszych przeglądarkach możesz wykonać następujące czynności:

document.querySelectorAll( ":hover" );

To da ci NodeList przedmiotów, które mysz jest obecnie w porządku w porządku dokumentu. Ostatni element w NodeList jest najbardziej szczegółowy, każdy poprzedni powinien być rodzicem, dziadkiem i tak dalej.


49
2018-03-07 04:36



To nie wydawało się działać, gdy przeciągałem <li> podczas gdy na drugim <li> elementy. - Seiyria
Zrobiłem skrzypce z $(':hover') ale to w zasadzie to samo: jsfiddle.net/pmrotule/2pks4tf6 - pmrotule
(function(){ var q = document.querySelectorAll(":hover"); return q[q.length-1]; })() - user
Mam przeczucie, że wykonanie tego jest okropne ... wzywanie tego mousemove może zranić wydajność - vsync


Chociaż poniższe pytania mogą nie odpowiadać na to pytanie, ponieważ jest to pierwszy wynik googlowania (pracownik Google może nie zadawać dokładnie tego samego pytania :), mam nadzieję, że dostarczy trochę dodatkowych danych.

W rzeczywistości istnieją dwa różne podejścia do uzyskania listy wszystkich elementów, na których mysz się obecnie znajduje (być może dla nowszych przeglądarek):

Podejście "strukturalne" - rosnące drzewo DOM

Tak jak w odpowiedzi na dhermana, można zadzwonić

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

Jednakże zakłada to, że tylko dzieci będą nakładać się na swoich przodków, co zwykle ma miejsce, ale nie jest to prawda w ogóle, szczególnie w przypadku SVG, gdzie element w różnych gałęziach drzewa DOM może nakładać się na siebie.

Podejście "wizualne" - oparte na "wizualnym" nakładaniu się

Ta metoda używa document.elementFromPoint(x, y) aby znaleźć najwyższy element, tymczasowo go ukryj (ponieważ natychmiast go odtworzymy w tym samym kontekście, przeglądarka tego nie wyrenderuje), a następnie przejdzie do drugiego najwyższego elementu ... Wygląda trochę hacky, ale zwraca co można się spodziewać, gdy są np. elementy rodzeństwa w drzewie zamykające się nawzajem. Proszę znajdź ten post po więcej szczegółów,

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

Wypróbuj oba i sprawdź ich różne zwroty.


32
2018-01-11 06:40



Bardzo mi to pomogło. Dzięki @ herrlich10. Co zaskakujące, twój kod obsługuje także sprawy z zagnieżdżonymi elementami potomnymi. - Vikram Deshmukh
Nie ma za co @ VikramDeshmukh ~ Miło wiedzieć, że :) - herrlich10
Wizualne podejście naprawdę fajne! Dzięki! - Mikhail
Jest to niezwykle przydatne. Dokładnie to, czego szukałem. Jak już powiedziałeś, querySelectorAll nie działa w każdym scenariuszu. - noobsharp
@ herrlich10 Wydaje się to być przyzwoitą polyfill dla developer.mozilla.org/en-US/docs/Web/API/Document/.... Jeśli ten interfejs API istnieje w obsługiwanym zestawie browserSet, myślę, że możesz go użyć. - dherman


Pęcherzyki zdarzeń najedź myszką, dzięki czemu możesz umieścić pojedynczego słuchacza na ciele i czekać, aż się zapalą, a następnie chwycić event.target lub event.srcElement:

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

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

5
2018-01-11 02:37



Podczas gdy ja sam używam uniwersalnych programów obsługi zdarzeń, byłoby to droższe od zasobów document.elementFromPoint(x, y). - John


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

4
2017-08-28 03:42



Przepraszam za zły sposób, w jaki traktowano cię na swoim (teraz usuniętym) pytaniu. Osobiście wolałbym, aby pytanie zostało cofnięte. Podczas, gdy był już zamknięty (moim zdaniem nieuczciwie) planowałem głosować, aby go ponownie otworzyć. Jednak biorąc pod uwagę liczbę pucharów, rozumiem, jeśli zdecydujesz się go usunąć. - halfer


Poniższy kod pomoże ci uzyskać element wskaźnika myszy. Wynikowe elementy zostaną wyświetlone w konsoli.

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

4
2017-08-19 15:48



Wymaga to przesunięcia kursora. Tak blisko, jak to tylko możliwe, nie o to tutaj pytamy. - Carles Alcolea
Nie działa, jeśli strona jest przewijana. Posługiwać się e.clientX i e.clientY zamiast tego (testowane na Firefox 59). - youen


Możesz spojrzeć na cel mouseover zdarzenie na jakimś odpowiednim przodku:

var currentElement = null;

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

Oto wersja demonstracyjna.


3
2018-01-11 01:36





elementFromPoint() dostaje pierwszy element w drzewie DOM. Zwykle nie wystarcza to programistom. Dlatego istnieje taka fajna funkcja:

Document.elementsFromPoint()

Zwraca tablicę obiektów elementów w podanych punktach.

Jest to obecnie funkcja eksperymentalna, która nie jest obsługiwana przez wszystkie przeglądarki, więc możesz jej użyć ta odpowiedź jako zabezpieczenie

| Chrome | Firefox | IE   | Opera | Safari
| 43.0   | 46.0    | 10.0 | ?     | No support

Więcej informacji i aktualna kompatybilność przeglądarki tutaj: https://developer.mozilla.org/en-US/docs/Web/API/document/elementsFromPoint


2
2017-08-04 09:45