evento Javascript quando a janela folhas rato navegador [duplicado]
-
13-09-2019 - |
Pergunta
Esta questão já tem uma resposta aqui:
Eu gostaria de algum código Javascript para ser executado quando o mouse deixa a janela do navegador. Eu só preciso apoiar Safari (WebKit).
Eu tentei colocar um manipulador mouseout na janela. Esse manipulador é chamado de forma confiável quando o mouse deixa a janela do navegador. Mas por causa da borbulhando também é chamado quando o mouse se move entre elementos no documento. Eu não consigo descobrir como determinar quando o mouse tem realmente deixou a janela e quando só se moveu entre os elementos.
Quando as folhas do rato da janela, exatamente é gerado um evento, e as aparece elemento de destino a ser o elemento o rato foi realmente acabou. Assim, verificando para ver se o elemento de destino é a janela ou documento não funciona. E envolvendo toda a página em um contendo div invisível não quer trabalhar: se o div é invisível, então o rato nunca será sobre ele, por isso não muda nada.
(A mesma coisa acontece se eu colocar o manipulador de documento ou document.body, exceto que surpreendentemente document.body não recebe eventos mouseover / mouseout quando o mouse entra ou sai uma parte vazia da janela, como o vazio espaço vertical criado por absolutamente posicionar um elemento com base:.. 0 Para que o espaço, documento ea janela vai ter mouseover / eventos mouseout com o alvo sendo , mas document.body não)
Algumas idéias que eu tive:
- Em cada evento mouseout, obter a posição real do mouse e ver se ele é de fato sobre a janela. Mas eu não sei se isso é realmente possível e parece que seria complicado para eliminar todas as condições de corrida.
- Também registrar um manipulador de mouseover e detectar casos em que mouseout não é precedido por (ou seguido logo por a) um mouseover. Mas isso exigiria um temporizador.
Nós usamos prototype.js tão idealmente eu gostaria de expressar a solução em termos de Event.observe de protótipo, mas eu posso descobrir isso parte.
Obrigado por todas as sugestões!
Solução
RESUMO: Isto pode ser feito de forma limpa, verificando a propriedade relatedTarget durante o evento mouseout. Se relatedTarget não é uma criança de documento, em seguida, o rato acabado de sair da janela. É fácil de fazer sozinho, mas se você não quer, algumas bibliotecas (Mootools, futuro Prototype ..) já cozido em termos de funcionalidade, e outros (protótipo atual) têm extensões disponíveis. No IE, você poderia passar a usar mouseleave, que é uma versão não-borbulhante de mouseout.
Detalhes:
IE tem eventos chamados mouseenter e mouseleave que são versões não borbulhando de mouseover e mouseout. Outros navegadores não, mas se o fizessem, estabelecendo um ouvinte mouseleave na janela ou documento faria o truque.
Um senhor chamado Ken Snyder vem para o resgate:
Em um mouseover, a relatedTarget referências de propriedade do nó de qual o ponteiro veio. Em um mouseout, as referências de propriedade relatedTarget o nó ao qual o ponteiro went.On qualquer caso, o escopo é o nó que o evento é attached.When o relatedTarget é um não filho do currentTarget, um evento mouseover é equivalente a um evento mouseenter e uma evento mouseout é equivalente a um evento mouseleave.
- http://kendsnyder.com/archives/6-MouseEnter- e-MouseLeave.html
Isto torna possível implementar mouseenter e mouseleave em outros navegadores. Na verdade, Ken fornece mesmo código Prototype a fazê-lo: http://kendsnyder.com/sandbox/enterleave /MouseEnterLeave.js
Duroth destacou em comentários que MooTools já inclui algo semelhante. (Graças Duroth.) Parece que o lançamento Prototype próximo (1.6.2) pode incluir essa funcionalidade, mas eu não consigo encontrar nada definido.
Outras dicas
Usando apenas javascript, nenhum protótipo ou jQuery etc.
<html>
<head>
<script type="text/javascript">
var mouseX = 0;
var mouseY = 0;
var counter = 0;
var mouseIsIn = true;
function wireEvent() {
window.addEventListener("mouseout",
function(e){
mouseX = e.pageX;
mouseY = e.pageY;
if ((mouseY >= 0 && mouseY <= window.innerHeight)
&& (mouseX >= 0 && mouseX <= window.innerWidth))
return;
//do something for mouse out
counter++;
mouseIsIn = false;
document.getElementById('in_out').innerHTML='out' + counter;
},
false);
window.addEventListener("mouseover",
function(e){
if(mouseIsIn)
return;
//do something for mouse over
counter++;
mouseIsIn = true;
document.getElementById('in_out').innerHTML='in' + counter;
},
false);
}
</script>
</head>
<body onload="wireEvent();">
<div id="in_out"> </div>
<div style="width:300px; height: 200px; background: red;">Dummy element</div>
</body>
</html>
UPDATE:
verificação adicional para a posição do mouse sobre mouseout
desencadeada quando se deslocam in / out elementos dentro do corpo. Se é dentro da janela, evento mouseout
não é acionado.
Também introduziu uma bandeira para o estado atual do mouse 'em' ou 'out' usando mouseIsIn
. Se é true
, mouseover
não será desencadeada também.
Talvez você pode definir um ouvinte para mouseover e mouseout document
, body
ou algum outro elemento que envolve todo o documento, e usar isso (salvando que isso aconteceu) como um gatilho para determinar se ele é um mouseout válido na janela?
Na falta deste, a sua primeira ideia (sobre check posição) deve funcionar muito bem. Qualquer evento passa ao longo do X / Y o evento ocorreu. Se é nada mais do que a altura / largura da janela, você deixou a janela real. Se é algo negativo, você deixou a janela. E, possivelmente, se é exatamente a altura / largura ou exatamente top: 0 ou esquerda:. 0, então você deixou a janela
Quando o mouse sai de qualquer elemento, incluindo a janela, o objeto de janela irá disparar um evento mouseout
e passar o objeto event
junto com ele.
Um dos itens do objeto de evento é chamado toElement
, que é um ponteiro para o elemento o rato acabado de entrar quando deixou o antigo. Mas quando as folhas do rato a janela, não existe tal toElement
assim que este item torna-se null
.
Ao testar se ou não este item é null
em um evento mouseout
, você pode dizer se o mouse esquerda da janela. Aqui está o código:
window.onmouseout=function(event){
if(event.toElement===null) console.log('the mouse left the window');
}
Seu problema vem de eventos mouseout sendo gerados para elementos dentro da janela, que, em seguida, borbulhar, conforme descrito na eventos W3C especificação . Você pode verificar qual elemento o evento foi realmente demitido em:
function mouseoutFunction(event) {
event = event || window.event;
var sender = event.srcElement || event.target;
}
Aqui está a minha solução baseada em um temporizador. O temporizador aqui é basicamente usado para dar uma chance para outros manipuladores de eventos (especificamente, onmouseover) para executar antes de decidir que o mosue está fora da janela. O tempo limite de 1 ms (na verdade em torno de 33ms, existe uma resolução mínima temporizador) dá um pouco de tempo para o mouseover ocorrer se ainda não tem.
var inWin=0;
window.onmouseout = function(e)
{
inWin--;
setTimeout(checkIfOut, 1);
}
window.onmouseover = function(e)
{
inWin++;
}
function checkIfOut()
{
if(!inWin)
{
//Yay! Mouse is out of the window (probably)
}
}
Você pode usar onmouseout
evento em uma janela em vez