319 votes

Comment obtenir la position de la souris sans événements (sans déplacer la souris) ?

Est-il possible d'obtenir la position de la souris avec JavaScript après le chargement de la page sans événement de mouvement de la souris (sans déplacer la souris) ?

66 votes

Rien d'anormal avec l'événement de déplacement de la souris. Seulement, dans certains cas, les utilisateurs ne déplacent pas la souris. Merci pour votre réponse.

2 votes

Norbert Tamas, la réponse de @SuperNova (qui n'a été ajoutée que cette année) montre que le mouseenter fonctionne bien dans ce cas, car il se déclenche au chargement de la page (si la souris est dans la fenêtre d'affichage). Cela ne fonctionnait pas de cette façon en 2010, ou est-ce simplement que personne n'a pensé à l'essayer ?

1 votes

@CrescentFresh Dans certains cas (comme les userscripts), vous ne voulez pas ralentir le navigateur en ajoutant de nombreux mousemove événements.

369voto

Tim Down Points 124501

La vraie réponse : Non, ce n'est pas possible.

OK, je viens de penser à un moyen. Superposez votre page avec un div qui couvre l'ensemble du document. À l'intérieur de cette div, créez (disons) 2.000 x 2.000 <a> (de sorte que les :hover pseudo-classe fonctionnera dans IE 6, voir), chacun d'une taille de 1 pixel. Créez un CSS :hover règle pour ceux <a> qui modifie une propriété (disons font-family ). Dans votre gestionnaire de charge, passez en revue chacun des 4 millions de fichiers <a> éléments, vérification currentStyle / getComputedStyle() jusqu'à ce que tu trouves celle avec la police de survol. Extrapolez à partir de cet élément pour obtenir les coordonnées dans le document.

N.B. NE FAITES PAS ÇA .

106 votes

Ha ha - à un moment donné, vous devriez faire des recherches sur Google et voir si vous pouvez trouver combien de personnes ont réellement mis en œuvre ce système.

6 votes

Actually, it is implementable without having to much CPU load (I think. I haven't been testing it). Sur dom ready construire les éléments <a> avec javascript, prendre la position de la souris et ensuite supprimer tous les éléments <a>. Sur mousemouse vous devriez avoir une autre fonction pour prendre la position de la souris. Bref, c'était hilarant.

22 votes

Peut-être pourrait-on rendre cela pratique avec la recherche binaire ? Boucle faisant une paire de <a> des éléments couvrant des rectangles donnés (en utilisant le positionnement absolu des éléments dimensionnés). <img> éléments, je suppose), en rétrécissant les rectangles à chaque fois. Oui, c'est ridicule, mais le fait de ne pas pouvoir obtenir cette information avant le premier déplacement de la souris l'est tout autant.

260voto

Peter Bailey Points 62125

Réponse courte : Non

Réponse longue : Noooooooooooooooooooooooooo

Réponse réelle : JavaScript ne dispose pas [encore ?] d'une API permettant d'interroger l'état de la souris (ou du clavier). Une façon d'accomplir ceci (connaître l'état de la souris - boutons en haut/en bas, position du curseur, etc.) est d'avoir des variables qui gardent la trace de chaque état, puis de mettre à jour ces variables par le biais de rappels de gestionnaires d'événements.

Exemple :

var mouse = {x: 0, y: 0};

document.addEventListener('mousemove', function(e){ 
    mouse.x = e.clientX || e.pageX; 
    mouse.y = e.clientY || e.pageY 
}, false);

De cette façon, chaque fois que vous voulez savoir où se trouve la souris, il suffit de regarder l'icône de la souris. mouse objet. Notez que lors du chargement initial de la page, à moins que la souris ne se soit déplacée, cette solution ne vous indique pas où se trouve réellement la souris.

127voto

SuperNova Points 147

Edit 2020 : Cela ne pas plus de travail. Il semble que les vendeurs de navigateurs aient corrigé ce problème. Comme la plupart des navigateurs reposent sur Chrome, il se peut que ce soit dans son noyau.

Ancienne réponse : Vous pouvez aussi hooker mouseenter (cet événement est déclenché après le rechargement de la page, lorsque le curseur de la souris est à l'intérieur de la page). L'extension du code de Corrupted devrait faire l'affaire :

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

Vous pouvez également définir x et y à null sur mouseleave-event. Ainsi vous pouvez vérifier si l'utilisateur est sur votre page avec son curseur.

11 votes

Cela semble être la seule réponse vraiment utile ici, ce qui est étrange. En effet (dans les dernières versions de Firefox, Chrome et IE11), le mouseenter se déclenche au chargement de la page et fournit les coordonnées correctes. Le comportement des navigateurs dans ce domaine a-t-il simplement changé au cours des dernières années ?

3 votes

En fait, "mouseenter" ne semble pas ajouter de valeur. J'ai testé avec la jsfiddle suivante dans Chrome et IE, et ils n'affichent pas les coordonnées jusqu'à ce que vous mettiez la souris sur le document interne (le panneau de résultat) : jsfiddle.net/xkpd784o/1

1 votes

@Proton : Déplacez votre souris dans le panneau des résultats AVANT que la page ne soit complètement chargée et ne la déplacez plus. Après le chargement, la page connaît immédiatement la position de la souris. Aucun mouvement de souris n'est nécessaire. Ainsi, mouseenter est également déclenché, lorsque la page est chargée et que la souris est à l'intérieur de la zone du document. C'est ce que le PO voulait à l'origine. Personne d'autre ne fournit cette réponse.

88voto

JHarding Points 213

Ce que vous pouvez faire, c'est créer des variables pour les x y y de votre curseur, les mettre à jour chaque fois que la souris se déplace et appeler une fonction sur un intervalle pour faire ce dont vous avez besoin avec la position stockée.

L'inconvénient, bien sûr, est qu'il faut au moins un mouvement initial de la souris pour que cela fonctionne. Tant que le curseur met à jour sa position au moins une fois, nous sommes en mesure de trouver sa position, qu'il se déplace à nouveau ou non.

var cursor_x = -1;
var cursor_y = -1;
document.onmousemove = function(event)
{
 cursor_x = event.pageX;
 cursor_y = event.pageY;
}
setInterval(check_cursor, 1000);
function check_cursor(){console.log('Cursor at: '+cursor_x+', '+cursor_y);}

Le code précédent se met à jour une fois par seconde avec un message indiquant où se trouve votre curseur. J'espère que cela vous aidera.

22 votes

Avez-vous lu le sujet de ce post ? L'OP demande comment obtenir les coordonnées de la souris sans utiliser un événement. Pourtant, votre message suggère d'utiliser l'événement onmousemove.

60 votes

@jake Bien que l'OP ait spécifiquement demandé une méthode non événementielle, cette réponse profite aux autres personnes qui sont venues ici pour chercher une réponse et éventuellement une solution de contournement. De plus, je considère que cette réponse est partiellement dans le sujet puisque, pour autant que je sache, c'est la meilleure méthode pour obtenir la position du curseur à un moment donné sans avoir à utiliser directement les événements. Cela dit, la réponse aurait pu être formulée de manière à énoncer le fait et à proposer une solution de contournement afin d'éviter le pinaillage dans les commentaires.

2 votes

@Pichan Ça ne m'a pas profité, parce que j'ai cherché un moyen de remplir ces cursorX/Y avant qu'un événement ne se produise.

11voto

Alex Peterson Points 126

La réponse de @Tim Down n'est pas performante si vous effectuez un rendu de 2.000 x 2.000. <a> éléments :

OK, je viens de penser à un moyen. Superposez votre page avec un div qui qui couvre l'ensemble du document. À l'intérieur, créez (disons) 2 000 x 2 000 éléments (pour que la pseudo-classe :hover fonctionne dans IE 6, voir), d'une taille de 1 pixel chacun. Créez une règle CSS :hover pour ces éléments qui modifie une propriété (disons font-family). Dans votre gestionnaire de chargement, passez en revue chacun des 4 millions d'éléments, en vérifiant que currentStyle / getComputedStyle() jusqu'à ce que vous trouviez celui qui possède la police de survol. Extrapolez à partir de cet élément pour obtenir les coordonnées dans le document.

N.B. NE FAITES PAS ÇA.

Mais il n'est pas nécessaire de rendre 4 millions d'éléments en une seule fois, utilisez plutôt la recherche binaire. Il suffit d'utiliser 4 <a> à la place :

  • Étape 1 : Considérez l'ensemble de l'écran comme la zone de recherche de départ.
  • Étape 2 : diviser la zone de recherche en 2 x 2 = 4 rectangles. <a> éléments
  • Étape 3 : Utilisation du getComputedStyle() fonction déterminant dans quel rectangle la souris se trouve
  • Étape 4 : réduisez la zone de recherche à ce rectangle et répétez l'étape 2.

De cette façon, vous devrez répéter ces étapes au maximum 11 fois, sachant que votre écran n'est pas plus large que 2048px.

Vous générerez donc un maximum de 11 x 4 = 44. <a> éléments.

Si vous n'avez pas besoin de déterminer la position de la souris au pixel près, une précision de 10px est acceptable. Vous répéteriez les étapes au maximum 8 fois, donc vous auriez besoin de dessiner au maximum 8 x 4 = 32. <a> éléments.

En outre, la génération puis la destruction de la <a> n'est pas performant car DOM est généralement lent. Au lieu de cela, vous pouvez simplement réutiliser les 4 éléments initiaux de la base de données. <a> et ajuster simplement leurs top , left , width y height pendant que vous passez en boucle les étapes.

Maintenant, en créant 4 <a> est aussi une surenchère. Au lieu de cela, vous pouvez réutiliser le même <a> lors des tests de getComputedStyle() dans chaque rectangle. Ainsi, au lieu de diviser la zone de recherche en 2 x 2 <a> réutilisent simplement un seul <a> en le déplaçant avec top y left les propriétés de style.

Donc, tout ce dont vous avez besoin est un simple <a> modifie son width y height max 11 fois, et modifier son top y left max 44 fois et vous aurez la position exacte de la souris.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X