Est-il possible d'obtenir la position de la souris avec JavaScript après le chargement d'une page sans événement de déplacement de la souris (sans déplacer la souris)?
Réponse réelle: non, ce n'est pas possible.
OK, je viens de penser à un moyen. Superposez votre page avec un div qui couvre tout le document. À l'intérieur de cela, créez (disons) 2 000 x 2 000 éléments <a>
(de sorte que la pseudo-classe :hover
fonctionne dans IE 6, voir), d'une taille d'un pixel chacun. Créez une règle CSS :hover
pour les éléments <a>
qui modifient une propriété (disons font-family
). Dans votre gestionnaire de charge, parcourez chacun des 4 millions d'éléments <a>
en cochant currentStyle
/getComputedStyle()
jusqu'à ce que vous trouviez celui avec la police de survol. Extrapoler à partir de cet élément pour obtenir les coordonnées dans le document.
N.B. NE FAITES PAS CELA .
Vous pouvez également relier mouseenter (cet événement est déclenché après le rechargement de la page, lorsque le curseur de la souris est dans 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 sur null sur mouseleave-event. Donc, vous pouvez vérifier si l'utilisateur est sur votre page avec son curseur.
Ce que vous pouvez faire, c'est créer des variables pour les coordonnées x
et 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 enregistrée.
L’inconvénient de ceci est bien sûr qu’au moins un mouvement initial de la souris est nécessaire 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 cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
setInterval(checkCursor, 1000);
function checkCursor(){
alert("Cursor at: " + cursorX + ", " + cursorY);
}
Le code précédent est mis à jour une fois par seconde avec un message indiquant l'emplacement de votre curseur. J'espère que ça aide.
Vous pouvez essayer quelque chose de similaire à ce que Tim Down a suggéré - mais au lieu d’avoir des éléments pour chaque pixel sur l’écran, créez seulement 2 à 4 éléments (cases) et modifiez leur emplacement, largeur et hauteur de manière dynamique pour diviser les emplacements encore possibles par 2-4 récursivement, trouvant ainsi rapidement l'emplacement réel de la souris.
Par exemple, les premiers éléments occupent les moitiés droite et gauche de l'écran, puis les moitiés supérieure et inférieure. A présent, nous savons déjà dans quel quart d’écran se trouve la souris, nous pouvons le répéter - découvrez quel quart de cet espace ...
La réponse de @Tim Down n'est pas performante si vous restituez 2 000 x 2 000 éléments <a>
:
OK, je viens de penser à un moyen. Superposez votre page avec un div que couvre tout le 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), chaque taille de 1 pixel. Créez une règle CSS: hover pour ces éléments cela change une propriété (disons font-famille). Dans votre gestionnaire de charge, Parcourez chacun des 4 millions d’éléments en vérifiant currentStyle/getComputedStyle () jusqu'à ce que vous trouviez celui avec le police de survol. Extrapoler en arrière de cet élément pour obtenir les coordonnées dans le document.
N.B. NE FAITES PAS CELA.
Mais vous ne devez pas générer 4 millions d'éléments à la fois, utilisez plutôt la recherche binaire. Utilisez simplement 4 éléments <a>
à la place:
<a>
getComputedStyle()
, déterminez dans quelle souris rectangulaire survoleDe 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.
Ainsi, vous générerez un maximum de 11 x 4 = 44 <a>
éléments.
Si vous n'avez pas besoin de déterminer exactement la position de la souris au pixel près, dites que la précision de 10px est correcte. Vous devez répéter les étapes au maximum 8 fois. Vous devez donc dessiner au maximum 8 x 4 = 32 <a>
éléments.
La génération et la destruction des éléments <a>
ne sont pas non plus exécutées, car DOM est généralement lent. Au lieu de cela, vous pouvez simplement réutiliser les 4 éléments <a>
initiaux et simplement ajuster leurs top
, left
, width
et height
lorsque vous parcourez des étapes.
Maintenant, créer 4 <a>
est également une overkill. Au lieu de cela, vous pouvez réutiliser le même élément <a>
lors du test de getComputedStyle()
dans chaque rectangle. Ainsi, au lieu de scinder la zone de recherche en 2 x 2 éléments <a>
, réutilisez simplement un seul élément <a>
en le déplaçant avec les propriétés de style top
et left
.
Donc, tout ce dont vous avez besoin est d’un seul élément <a>
, changez sa width
et height
max 11 fois, et changez sa top
et left
max 44 fois et vous obtiendrez la position exacte de la souris.
J'imagine que vous avez peut-être une page parent avec un minuteur et qu'après un certain temps ou une tâche terminée, vous transférez l'utilisateur vers une nouvelle page. Maintenant, vous voulez la position du curseur, et comme ils attendent, ils ne touchent pas nécessairement la souris. Suivez donc la souris sur la page parente à l'aide d'événements standard et transmettez la dernière valeur à la nouvelle page dans une variable get ou post.
Vous pouvez utiliser le code de JHarding sur votre page parent afin que la dernière position soit toujours disponible dans une variable globale:
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
Cela n’aidera pas les utilisateurs qui accèdent à cette page par un moyen autre que votre page parent.
La solution la plus simple mais pas précise à 100%
$(':hover').last().offset()
Résultat: {top: 148, left: 62.5}
Le résultat dépend de la taille de l'élément le plus proche et renvoie undefined
lorsque l'utilisateur a basculé l'onglet
Vous n'avez pas besoin de déplacer la souris pour obtenir l'emplacement du curseur. L'emplacement est également signalé pour des événements autres que mousemove . Voici un click-event à titre d'exemple:
document.body.addEventListener('click',function(e)
{
console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});
J'ai implémenté une recherche horizontale/verticale (créez d'abord une division complète avec des liens de lignes verticales disposés horizontalement, puis créez une division complète avec des liens de lignes horizontales disposés verticalement et voyez simplement lequel est en état de survol), comme dans Tim Tim ça marche assez vite. Malheureusement, cela ne fonctionne pas sur Chrome 32 sur KDE.
jsfiddle.net/5XzeE/4/
Je pense que je peux avoir une solution raisonnable sans compter les divs et les pixels..lol
Utilisez simplement une image d'animation ou un intervalle de temps d'une fonction. vous aurez toujours besoin d'un événement de souris une fois, mais juste pour l'initier, mais techniquement, vous le positionnez où vous voulez.
Essentiellement, nous suivons un div fictif à tout moment sans déplacer la souris.
// create a div(#mydiv) 1px by 1px set opacity to 0 & position:absolute;
Voici la logique ..
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);
}
Riffing on @ SuperNova's answer , voici une approche utilisant les classes ES6 qui maintient le contexte de this
correct dans votre rappel:
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));
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;
}