¿Es posible obtener la posición del mouse con JavaScript después de cargar la página sin ningún evento de movimiento del mouse (sin mover el mouse)?
mousemove
eventos.
¿Es posible obtener la posición del mouse con JavaScript después de cargar la página sin ningún evento de movimiento del mouse (sin mover el mouse)?
mousemove
eventos.
Respuestas:
Respuesta real: No, no es posible.
OK, acabo de pensar en una manera. Superponga su página con un div que cubra todo el documento. Dentro de eso, cree (digamos) 2.000 x 2.000 <a>
elementos (para que la :hover
pseudo-clase funcione en IE 6, vea), cada uno de 1 píxel de tamaño. Cree una :hover
regla CSS para aquellos <a>
elementos que cambian una propiedad (digamos font-family
). En su controlador de carga, recorra cada uno de los 4 millones de <a>
elementos, verificando currentStyle
/ getComputedStyle()
hasta encontrar el que tiene la fuente de desplazamiento. Extrapolar hacia atrás desde este elemento para obtener las coordenadas dentro del documento.
NB NO HAGAS ESTO .
<a>
elementos que cubren los rectángulos dados ( <img>
supongo que usando la posición absoluta de los elementos de tamaño ), reduciendo los rectángulos cada vez. Sí, es ridículo, pero no es posible obtener esta información antes del primer movimiento del mouse.
Editar 2020: esto ya no funciona. Parece que los proveedores de navegadores lo resolvieron. Debido a que la mayoría de los navegadores dependen del cromo, podría estar en su núcleo.
Respuesta anterior: también puede conectar mouseenter (este evento se activa después de volver a cargar la página, cuando el mousecursor está dentro de la página). Extender el código de Corrupted debería hacer el truco:
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;
}
También puede establecer x e y como nulo en mouseleave-event. Para que pueda verificar si el usuario está en su página con su cursor.
mouseleave
evento que establece x
y y
vuelve a null
o'undefined'
Lo que puede hacer es crear variables para las coordenadas x
y y
de su cursor, actualizarlas cada vez que se mueve el mouse y llamar a una función en un intervalo para hacer lo que necesita con la posición almacenada.
La desventaja de esto, por supuesto, es que se requiere al menos un movimiento inicial del mouse para que funcione. Mientras el cursor actualice su posición al menos una vez, podremos encontrar su posición independientemente de si se mueve de nuevo.
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
setInterval(checkCursor, 1000);
function checkCursor(){
alert("Cursor at: " + cursorX + ", " + cursorY);
}
El código anterior se actualiza una vez por segundo con un mensaje de dónde está el cursor. Espero que esto ayude.
cursorX/Y
variables antes de que ocurra cualquier evento.
Podría intentar algo similar a lo que sugirió Tim Down, pero en lugar de tener elementos para cada píxel en la pantalla, cree solo 2-4 elementos (cuadros) y cambie su ubicación, ancho y altura dinámicamente para dividir las ubicaciones posibles en la pantalla por 2-4 recursivamente, encontrando así la ubicación real del mouse rápidamente.
Por ejemplo, los primeros elementos toman la mitad derecha e izquierda de la pantalla, luego la mitad superior e inferior. Por ahora ya sabemos en qué cuarto de la pantalla se encuentra el mouse, podemos repetir: descubra qué cuarto de este espacio ...
La respuesta de @Tim Down no es eficaz si representa 2.000 x 2.000 <a>
elementos:
OK, acabo de pensar en una manera. Superponga su página con un div que cubra todo el documento. Dentro de eso, cree (digamos) 2.000 x 2.000 elementos (para que la pseudoclase: hover funcione en IE 6, vea), cada uno de 1 píxel de tamaño. Cree un CSS: regla de desplazamiento para aquellos elementos que cambian una propiedad (digamos font-family). En su controlador de carga, recorra cada uno de los 4 millones de elementos, verifique currentStyle / getComputedStyle () hasta que encuentre el que tiene la fuente de desplazamiento. Extrapolar hacia atrás desde este elemento para obtener las coordenadas dentro del documento.
NB NO HAGAS ESTO.
Pero no tiene que representar 4 millones de elementos a la vez, en su lugar use la búsqueda binaria. Solo use 4 <a>
elementos en su lugar:
<a>
elementos rectangulares getComputedStyle()
función, determine en qué rectángulo se desplaza el mouseDe esta manera, deberá repetir estos pasos un máximo de 11 veces, teniendo en cuenta que su pantalla no es más ancha que 2048px.
Entonces generarás un máximo de 11 x 4 = 44 <a>
elementos.
Si no necesita determinar la posición del mouse exactamente en un píxel, pero digamos que la precisión de 10px está bien. Debería repetir los pasos como máximo 8 veces, por lo que necesitaría dibujar un máximo de 8 x 4 = 32 <a>
elementos.
Tampoco se genera y luego se destruyen los <a>
elementos, ya que DOM es generalmente lento. En su lugar, sólo puede volver a utilizar los 4 primeros <a>
elementos y simplemente ajustar su top
, left
, width
y height
como se bucle a través de los pasos.
Ahora, crear 4 también <a>
es una exageración. En cambio, puede reutilizar el mismo <a>
elemento para cuando realice la prueba getComputedStyle()
en cada rectángulo. Así, en lugar de dividir el área de búsqueda en 2 x 2 <a>
elementos que acabamos de volver a utilizar un solo <a>
elemento moviéndolo con top
y left
propiedades de estilo.
Por lo tanto, todo lo que necesita es que un solo <a>
elemento cambie su width
y height
máximo 11 veces, y cambie su top
y left
máximo 44 veces y tendrá la posición exacta del mouse.
La solución más simple pero no 100% precisa
$(':hover').last().offset()
Resultado: {top: 148, left: 62.5}
el resultado depende del tamaño del elemento más cercano y se devuelve undefined
cuando el usuario cambia la pestaña
undefined
independientemente. ¿Puedes explicar cómo usar esto?
undefined
cuando el cursor no estuviera flotando sobre ningún elemento (o cuando el navegador perdiera el foco). Puede que necesite establecer un intervalo de tiempo si está probando desde la consola ..
setTimeout
trabajó. Estaba usando jsfiddle y tienes razón, nunca llegó a un evento flotante porque redibuja el DOM cada vez que haces clic en reproducir. Recomendaría agregar esta pista para otros.
Imagino que tal vez tenga una página principal con un temporizador y después de un cierto tiempo o una tarea completada, reenvíe al usuario a una nueva página. Ahora desea la posición del cursor y, como están esperando, no necesariamente tocan el mouse. Por lo tanto, siga el mouse en la página principal utilizando eventos estándar y pase el último valor a la nueva página en una variable get o post.
Puede usar el código de JHarding en su página principal para que la última posición siempre esté disponible en una variable global:
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
Esto no ayudará a los usuarios que naveguen a esta página por otros medios que no sean su página principal.
Implementé una búsqueda horizontal / vertical (primero haga un div lleno de enlaces de línea vertical dispuestos horizontalmente, luego haga un div lleno de enlaces de línea horizontal dispuestos verticalmente, y simplemente vea cuál tiene el estado de desplazamiento) como la idea de Tim Down anterior, y Funciona bastante rápido. Lamentablemente, no funciona en Chrome 32 en KDE.
jsfiddle.net/5XzeE/4/
No tiene que mover el mouse para obtener la ubicación del cursor. La ubicación también se informa en eventos que no sean mousemove . Aquí hay un evento de clic como ejemplo:
document.body.addEventListener('click',function(e)
{
console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});
Refiriéndose a la respuesta de @ SuperNova , aquí hay un enfoque que usa clases ES6 que mantiene el contexto this
correcto en su devolución de llamada:
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));
Aquí está mi solución. Exporta window.currentMouseX y window.currentMouseY propiedades que puede utilizar en cualquier lugar. Utiliza la posición de un elemento suspendido (si lo hay) inicialmente y luego escucha los movimientos del mouse para establecer los valores correctos.
(function () {
window.currentMouseX = 0;
window.currentMouseY = 0;
// Guess the initial mouse position approximately if possible:
var hoveredElement = document.querySelectorAll(':hover');
hoveredElement = hoveredElement[hoveredElement.length - 1]; // Get the most specific hovered element
if (hoveredElement != null) {
var rect = hoveredElement.getBoundingClientRect();
// Set the values from hovered element's position
window.currentMouseX = window.scrollX + rect.x;
window.currentMouseY = window.scrollY + rect.y;
}
// Listen for mouse movements to set the correct values
document.addEventListener('mousemove', function (e) {
window.currentMouseX = e.pageX;
window.currentMouseY = e.pageY;
});
}())
Compositor CMS Fuente: https://github.com/ocproducts/composr/commit/a851c19f925be20bc16bfe016be42924989f262e#diff-b162dc9c35a97618a96748639ff41251R1202
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;
}
Creo que puedo tener una solución razonable sin contar divs y píxeles ... jajaja
Simplemente use el marco de animación o el intervalo de tiempo de una función. aún necesitará un evento de mouse una vez, aunque solo sea para iniciar, pero técnicamente lo posiciona donde quiera.
Esencialmente, estamos rastreando un div dummy en todo momento sin movimiento del mouse.
// create a div(#mydiv) 1px by 1px set opacity to 0 & position:absolute;
Debajo está la lógica ...
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);
}