É possível obter a posição do mouse com JavaScript após o carregamento da página sem nenhum evento de movimento do mouse (sem mover o mouse)?
mousemove
eventos.
É possível obter a posição do mouse com JavaScript após o carregamento da página sem nenhum evento de movimento do mouse (sem mover o mouse)?
mousemove
eventos.
Respostas:
Resposta real: Não, não é possível.
OK, eu apenas pensei em uma maneira. Sobreponha sua página com uma div que cubra todo o documento. Dentro disso, crie (digamos) 2.000 x 2.000 <a>
elementos (para que a :hover
pseudo-classe funcione no IE 6, veja), cada tamanho de 1 pixel. Crie uma :hover
regra CSS para os <a>
elementos que alteram uma propriedade (digamos font-family
). No seu manipulador de carga, percorra cada um dos 4 milhões de <a>
elementos, verificando currentStyle
/ getComputedStyle()
até encontrar aquele com a fonte de foco. Faça uma extrapolação desse elemento para obter as coordenadas dentro do documento.
NB NÃO FAZER ISSO .
<a>
elementos cobrindo determinados retângulos (usando posicionamento absoluto de <img>
elementos dimensionados , suponho), encolhendo os retângulos a cada vez. Sim, é ridículo, mas não é possível obter essas informações antes da primeira troca de mouse.
Edit 2020: Isso não funciona mais. Parece que os fornecedores de navegadores corrigiram isso. Como a maioria dos navegadores depende do cromo, ele pode estar em seu núcleo.
Resposta antiga: Você também pode conectar o mouse (esse evento é acionado após a recarga da página, quando o mouse está dentro da página). Estender o código de Corrupted deve fazer o truque:
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;
}
Você também pode definir x e y como nulos no evento mouseleave-event. Assim, você pode verificar se o usuário está na sua página com o cursor.
mouseleave
evento que conjuntos x
e y
de volta para null
ou'undefined'
O que você pode fazer é criar variáveis para as coordenadas x
e y
do seu cursor, atualizá-las sempre que o mouse se mover e chamar uma função em um intervalo para fazer o que você precisa com a posição armazenada.
A desvantagem disso é que, pelo menos, um movimento inicial do mouse é necessário para que ele funcione. Desde que o cursor atualize sua posição pelo menos uma vez, podemos encontrar sua posição, independentemente de ele se mover novamente.
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
setInterval(checkCursor, 1000);
function checkCursor(){
alert("Cursor at: " + cursorX + ", " + cursorY);
}
O código anterior é atualizado uma vez por segundo com uma mensagem de onde está o cursor. Eu espero que isso ajude.
cursorX/Y
variáveis antes que qualquer evento acontecesse.
Você pode tentar algo semelhante ao que Tim Down sugeriu - mas em vez de ter elementos para cada pixel na tela, crie apenas 2 a 4 elementos (caixas) e altere sua localização, largura e altura dinamicamente para dividir os locais ainda possíveis na tela por 2-4 recursivamente, encontrando assim a localização real do mouse rapidamente.
Por exemplo - os primeiros elementos ficam com a metade direita e esquerda da tela, depois a metade superior e inferior. Até agora já sabemos em que quarto da tela o mouse está localizado, somos capazes de repetir - descubra qual quarto desse espaço ...
A resposta de @Tim Down não tem desempenho se você renderizar 2.000 x 2.000 <a>
elementos:
OK, acabei de pensar em uma maneira. Sobreponha sua página com uma div que cubra todo o documento. Dentro disso, crie (digamos) 2.000 x 2.000 elementos (para que a pseudo classe: hover funcione no IE 6, veja), cada tamanho de 1 pixel. Crie uma regra CSS: hover para os elementos que alteram uma propriedade (digamos família de fontes). No seu manipulador de carga, percorra cada um dos 4 milhões de elementos, verificando currentStyle / getComputedStyle () até encontrar aquele com a fonte hover. Faça uma extrapolação desse elemento para obter as coordenadas dentro do documento.
NB NÃO FAZER ISSO.
Mas você não precisa renderizar 4 milhões de elementos de uma só vez; em vez disso, use a pesquisa binária. Basta usar 4 <a>
elementos:
<a>
elementos retangulares getComputedStyle()
função, determine em qual mouse retângulo passa o mouseDessa forma, você precisará repetir essas etapas no máximo 11 vezes, considerando que sua tela não excede 2048px.
Então você irá gerar no máximo 11 x 4 = 44 <a>
elementos.
Se você não precisar determinar a posição do mouse exatamente em um pixel, mas diga que a precisão de 10px está correta. Você repetiria as etapas no máximo 8 vezes, portanto, seria necessário desenhar no máximo 8 x 4 = 32 <a>
elementos.
Também gerar e destruir os <a>
elementos não é performatizado, pois o DOM geralmente é lento. Em vez disso, você pode simplesmente reutilizar os 4 primeiros <a>
elementos e apenas ajustar o seu top
, left
, width
e height
como você percorrer as etapas.
Agora, criar 4 também <a>
é um exagero. Em vez disso, você pode reutilizar o mesmo <a>
elemento para testar getComputedStyle()
em cada retângulo. Portanto, em vez de dividir a área de pesquisa em <a>
elementos 2 x 2 , apenas reutilize um único <a>
elemento movendo-o com as propriedades top
e left
style.
Portanto, tudo o que você precisa é de um único <a>
elemento, altere seu width
e height
máximo 11 vezes, e altere seu top
e left
máximo 44 vezes, e você terá a posição exata do mouse.
A solução mais simples, mas não 100% precisa
$(':hover').last().offset()
Resultado: {top: 148, left: 62.5}
o resultado depende do tamanho do elemento mais próximo e retorna undefined
quando o usuário alterna a guia
undefined
independentemente. Você pode elaborar como usar isso?
undefined
quando o cursor não estivesse pairando nenhum elemento (ou quando o navegador perdesse o foco). Pode ser necessário definir um intervalo de tempo, se você está testando a partir do console ..
setTimeout
trabalhou. Eu estava usando jsfiddle e você está certo, ele nunca atinge um evento de foco, porque redesenha o DOM toda vez que você clica em reproduzir. Eu recomendaria adicionar essa dica para outras pessoas.
Eu imagino que talvez você tenha uma página pai com um cronômetro e, após um certo período de tempo ou uma tarefa ser concluída, encaminhe o usuário para uma nova página. Agora você quer a posição do cursor e, como eles estão esperando, não estão necessariamente tocando o mouse. Portanto, acompanhe o mouse na página pai usando eventos padrão e passe o último valor para a nova página em uma variável get ou post.
Você pode usar o código do JHarding na página pai para que a posição mais recente esteja sempre disponível em uma variável global:
var cursorX;
var cursorY;
document.onmousemove = function(e){
cursorX = e.pageX;
cursorY = e.pageY;
}
Isso não ajudará os usuários que navegam para esta página por outros meios que não a sua página pai.
Eu implementei uma pesquisa horizontal / vertical (primeiro faça uma div cheia de links de linhas verticais organizados horizontalmente, depois faça uma div cheia de links de linhas horizontais organizadas verticalmente e simplesmente veja qual deles tem o estado de foco), como a idéia de Tim Down acima, e funciona muito rápido. Infelizmente, não funciona no Chrome 32 no KDE.
jsfiddle.net/5XzeE/4/
Você não precisa mover o mouse para obter a localização do cursor. O local também é relatado em outros eventos que não o mouse remoto . Aqui está um evento de clique como exemplo:
document.body.addEventListener('click',function(e)
{
console.log("cursor-location: " + e.clientX + ',' + e.clientY);
});
Examinando a resposta da @ SuperNova , aqui está uma abordagem usando as classes ES6 que mantém o contexto this
correto no retorno de chamada:
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));
Aqui está a minha solução. Ela exporta window.currentMouseX e window.currentMouseY propriedades que você pode usar em qualquer lugar. Ele usa a posição de um elemento pairado (se houver) inicialmente e depois escuta os movimentos do mouse para definir os valores corretos.
(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;
});
}())
Fonte do CMS do Composr : 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;
}
Acho que posso ter uma solução razoável sem contar divs e pixels .. lol
Basta usar o quadro de animação ou um intervalo de tempo de uma função. você ainda precisará de um evento de mouse uma vez, apenas para iniciar, mas tecnicamente você o posiciona onde quiser.
Essencialmente, estamos rastreando uma div falsa o tempo todo, sem o movimento do mouse.
// create a div(#mydiv) 1px by 1px set opacity to 0 & position:absolute;
Abaixo está a 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);
}