web-dev-qa-db-fra.com

Déterminer l'élément sur lequel le pointeur de la souris se trouve en Javascript

Je veux une fonction qui me dit de quel élément se trouve le curseur de la souris.

Ainsi, par exemple, si la souris de l'utilisateur est au-dessus de cette zone de texte (avec l'ID wmd-input), l'appel de window.which_element_is_the_mouse_on() sera fonctionnellement équivalent à $("#wmd-input").

85
Tom Lehman

DEMO

Il existe une fonction vraiment géniale appelée document.elementFromPoint qui fait ce que cela ressemble.

Ce dont nous avons besoin, c'est de trouver les coordonnées x et y de la souris, puis de l'appeler en utilisant ces valeurs:

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

document.elementFromPoint

Objet d'événement jQuery

119
qwertymk

Dans les nouveaux navigateurs, vous pouvez effectuer les opérations suivantes:

document.querySelectorAll( ":hover" );

Cela vous donnera une liste de noeuds d'éléments sur lesquels la souris est actuellement placée dans l'ordre des documents. Le dernier élément de la liste de noeuds est le plus spécifique. Chaque élément précédent doit être un parent, un grand-parent, etc.

53
dherman

Bien que les éléments suivants ne répondent peut-être pas réellement à la question, puisqu'il s'agit du premier résultat de la recherche sur Google (le chercheur ne posera peut-être pas exactement la même question :), espérons qu'il fournira des informations supplémentaires.

Il existe actuellement deux approches différentes pour obtenir la liste de tous les éléments actuellement survolés par la souris (peut-être pour les nouveaux navigateurs):

L'approche "structurelle" - Arbre DOM croissant

Comme dans la réponse de dherman, on peut appeler

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

Cependant, cela suppose que seuls les enfants superposent leurs ancêtres, ce qui est généralement le cas, mais ce n'est pas vrai en général, en particulier lorsqu'il s'agit de SVG où des éléments de différentes branches de l'arbre DOM peuvent se chevaucher.

L'approche "visuelle" - basée sur le chevauchement "visuel"

Cette méthode utilise document.elementFromPoint(x, y) pour trouver l'élément le plus haut, le masquer temporairement (puisque nous le récupérons immédiatement dans le même contexte, le navigateur ne le rendra pas réellement), puis poursuivons pour trouver le deuxième élément le plus en haut ... mais il renvoie ce que vous attendez quand il y a, par exemple, des éléments de frères et sœurs dans un arbre qui se ferment mutuellement. Veuillez trouver cet article pour plus de détails,

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

Essayez les deux et vérifiez leurs déclarations.

39
herrlich10

elementFromPoint() obtient uniquement le premier élément de l'arborescence DOM. Ce n'est généralement pas suffisant pour les besoins des développeurs. Par conséquent, il y a cette fonction de Nice:

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

Ceci retourne un tableau de tous les objets élément sous les points donnés.

Pour les navigateurs plus anciens qui ne sont pas pris en charge, vous pouvez utiliser cette réponse comme solution de secours

Plus d'informations sur la compatibilité des anciens navigateurs ici: https://developer.mozilla.org/en-US/docs/Web/API/document/elementsFromPoint

6
Karl Adler

Les événements survolant la souris survolent les bulles pour vous permettre de placer un seul auditeur sur le corps et d’attendre qu’ils se manifestent, puis prenez le event.target ou le event.srcElement:

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

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

Vous pouvez regarder la cible de l'événement mouseover sur un ancêtre approprié:

var currentElement = null;

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

Voici une démo.

4
Ry-

Le code suivant vous aidera à obtenir un élément du pointeur de la souris. Les éléments résultants seront affichés dans la console.

document.addEventListener('mousemove', function(e) {
    console.log(document.elementFromPoint(e.pageX, e.pageY)); 
})
4
saikumar
<!-- 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
Dip M

La cible de l'événement mousemove DOM est l'élément DOM le plus haut sous le curseur lorsque la souris se déplace:

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

Ceci est similaire à la solution de @Philip Walton, mais ne nécessite pas jQuery ou un setInterval.

1
Max Heiber

Permettez-moi de commencer par dire que je ne recommande pas d'utiliser la méthode que je vais suggérer. Il vaut bien mieux utiliser le développement piloté par les événements et lier les événements uniquement aux éléments qui vous intéressent, savoir si la souris est terminée avec mouseover, mouseout, mouseenter, mouseleave, etc.

Si vous DEVEZ absolument savoir de quel élément se trouve la souris, vous devez écrire une fonction qui lie l'événement mouseover à tout ce qui se trouve dans le DOM, puis stocker quel que soit l'élément actuel dans une variable.

Vous pourriez tellement quelque chose comme ça:

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

Fondamentalement, j'ai créé une fonction immédiate qui définit l'événement sur tous les éléments et stocke l'élément actuel dans la fermeture pour minimiser votre encombrement.

Voici une démonstration en cours qui appelle window.which_element_is_the_mouse_on chaque seconde et enregistre l’élément actuellement utilisé par la souris sur la console.

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

0
Philip Walton

Ancienne question, mais voici une solution pour ceux qui peuvent encore être en difficulté. Vous souhaitez ajouter un événement mouseover sur l'élément 'parent' du ou des éléments enfants à détecter. Le code ci-dessous vous montre comment vous y prendre.

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

DEMO SUR CODEPEN

0
UZOR

DEMO: D Déplacez votre souris dans la fenêtre d’extrait de code: D

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

0
Zibri