Eu quero ser capaz de detectar quando o mouse sai da janela para que eu possa impedir que eventos sejam disparados enquanto o mouse do usuário está em outro lugar.
Alguma ideia de como fazer isso?
Eu quero ser capaz de detectar quando o mouse sai da janela para que eu possa impedir que eventos sejam disparados enquanto o mouse do usuário está em outro lugar.
Alguma ideia de como fazer isso?
Respostas:
Este tipo de comportamento é geralmente desejado durante a implementação do comportamento arrastar e soltar em uma página html. A solução abaixo foi testada no IE 8.0.6, FireFox 3.6.6, Opera 10.53 e Safari 4 em uma máquina MS Windows XP.
Primeiro, uma pequena função de Peter-Paul Koch; manipulador de eventos para vários navegadores:
function addEvent(obj, evt, fn) {
if (obj.addEventListener) {
obj.addEventListener(evt, fn, false);
}
else if (obj.attachEvent) {
obj.attachEvent("on" + evt, fn);
}
}
Em seguida, use este método para anexar um manipulador de eventos ao evento mouseout dos objetos de documento:
addEvent(document, "mouseout", function(e) {
e = e ? e : window.event;
var from = e.relatedTarget || e.toElement;
if (!from || from.nodeName == "HTML") {
// stop your drag event here
// for now we can just use an alert
alert("left window");
}
});
Por fim, aqui está uma página html com o script incorporado para depuração:
<html>
<head>
<script type="text/javascript">
function addEvent(obj, evt, fn) {
if (obj.addEventListener) {
obj.addEventListener(evt, fn, false);
}
else if (obj.attachEvent) {
obj.attachEvent("on" + evt, fn);
}
}
addEvent(window,"load",function(e) {
addEvent(document, "mouseout", function(e) {
e = e ? e : window.event;
var from = e.relatedTarget || e.toElement;
if (!from || from.nodeName == "HTML") {
// stop your drag event here
// for now we can just use an alert
alert("left window");
}
});
});
</script>
</head>
<body></body>
</html>
Se você está usando jQuery, que tal este código curto e doce -
$(document).mouseleave(function () {
console.log('out');
});
Este evento será acionado sempre que o mouse não estiver na sua página como você deseja. Basta alterar a função para fazer o que quiser.
E você também pode usar:
$(document).mouseenter(function () {
console.log('in');
});
Para disparar quando o mouse entrar de volta na página novamente.
Isso funciona para mim:
addEvent(document, 'mouseout', function(evt) {
if (evt.toElement == null && evt.relatedTarget == null) {
alert("left window");
}
});
addEvent
?
if (!evt.toElement && !evt.relatedTarget)
Para detectar a saída do mouse sem levar em conta a barra de rolagem e o campo de preenchimento automático ou inspecionar:
document.addEventListener("mouseleave", function(event){
if(event.clientY <= 0 || event.clientX <= 0 || (event.clientX >= window.innerWidth || event.clientY >= window.innerHeight))
{
console.log("I'm out");
}
});
Explicações das condições:
event.clientY <= 0 is when the mouse leave from the top
event.clientX <= 0 is when the mouse leave from the left
event.clientX >= window.innerWidth is when the mouse leave from the right
event.clientY >= window.innerHeight is when the mouse leave from the bottom
============================ EDITAR =========================== ======
document.addEventListener ("mouseleave") parece não ser acionado na nova versão do firefox, mouseleave precisa ser anexado a um elemento como o corpo ou um elemento filho.
Eu sugiro usar ao invés
document.body.addEventListener("mouseleave")
Ou
window.addEventListener("mouseout")
Usar o evento onMouseLeave evita bolhas e permite detectar facilmente quando o mouse sai da janela do navegador.
<html onmouseleave="alert('You left!')"></html>
document.onmouseleave = function() { alert('You left!') };
não use document.body que dispara uma barra de rolagem que encolhe o corpo! Código para prevenir fogo em elementos não é necessário. Boa explicação: developer.mozilla.org/en-US/docs/Web/API/Element/…
Nenhuma dessas respostas funcionou para mim. Agora estou usando:
document.addEventListener('dragleave', function(e){
var top = e.pageY;
var right = document.body.clientWidth - e.pageX;
var bottom = document.body.clientHeight - e.pageY;
var left = e.pageX;
if(top < 10 || right < 20 || bottom < 10 || left < 10){
console.log('Mouse has moved out of window');
}
});
Estou usando isso para arrastar e soltar o widget de upload de arquivos. Não é absolutamente preciso, sendo acionado quando o mouse chega a uma certa distância da borda da janela.
Tentei todas as opções acima, mas nada parece funcionar conforme o esperado. Depois de um pouco de pesquisa descobri que e.relatedTarget é o html apenas antes de o rato sai da janela .
Então ... eu acabei com isso:
document.body.addEventListener('mouseout', function(e) {
if (e.relatedTarget === document.querySelector('html')) {
console.log('We\'re OUT !');
}
});
Informe-nos se encontrar algum problema ou melhoria!
Atualização de 2019
(como o usuário 1084282 descobriu)
document.body.addEventListener('mouseout', function(e) {
if (!e.relatedTarget && !e.toElement) {
console.log('We\'re OUT !');
}
});
relatedTarget
é nulo quando o mouse sai da janela. Inspirado na resposta de @ user1084282, mude para isto: if(!e.relatedTarget && !e.toElement) { ... }
e funciona
if(!e.relatedTarget && !e.toElement)
vez da condição na resposta real. Ele detecta que o mouse saiu do corpo do documento.
Retiro o que disse. É possível. Eu escrevi esse código, funciona perfeitamente.
window.onload = function() {
$span = document.getElementById('text');
window.onmouseout = function() {
$span.innerHTML = "mouse out";
}
window.onmousemove = function() {
$span.innerHTML = "mouse in";
}
}
trabalha em cromo, firefox, ópera. Aint testado no IE, mas presume que funciona.
editar. O IE, como sempre, causa problemas. Para fazer funcionar no IE, substitua os eventos de janela para documento:
window.onload = function() {
$span = document.getElementById('text');
document.onmousemove = function() {
$span.innerHTML = "mouse move";
}
document.onmouseout = function() {
$span.innerHTML = "mouse out";
}
}
combine-os para a detecção do cursor crossbrowser kick ass o0: P
aplique este css:
html
{
height:100%;
}
Isso garante que o elemento html ocupe toda a altura da janela.
aplique este jquery:
$("html").mouseleave(function(){
alert('mouse out');
});
O problema com o mouseover e o mouseout é que, se você passar o mouse sobre / fora do html para um elemento filho, o evento será ativado. A função que dei não é acionada ao passar o mouse para um elemento filho. Só é ativado quando você move o mouse para fora / dentro da janela
apenas para você saber que pode fazer isso quando o usuário passar o mouse na janela:
$("html").mouseenter(function(){
alert('mouse enter');
});
Tentei um após o outro e encontrei a melhor resposta na época:
https://stackoverflow.com/a/3187524/985399
Eu pulo os navegadores antigos, então tornei o código mais curto para funcionar em navegadores modernos (IE9 +)
document.addEventListener("mouseout", function(e) {
let t = e.relatedTarget || e.toElement;
if (!t || t.nodeName == "HTML") {
console.log("left window");
}
});
document.write("<br><br>PROBLEM<br><br><div>Mouseout trigg on HTML elements</div>")
Aqui você vê o suporte do navegador
Isso foi bem curto eu pensei
Mas ainda havia um problema porque o "mouseout" disparava em todos os elementos do documento .
Para evitar que isso aconteça, use o mouseeleave (IE5.5 +). Veja a boa explicação no link.
O código a seguir funciona sem acionar elementos dentro do elemento para estar dentro ou fora dele. Tente também soltar e arrastar para fora do documento.
var x = 0
document.addEventListener("mouseleave", function(e) { console.log(x++)
})
document.write("<br><br>SOLUTION<br><br><div>Mouseleave do not trigg on HTML elements</div>")
Você pode definir o evento em qualquer elemento HTML. Não document.body
ative o evento , porque a barra de rolagem do Windows pode encolher o corpo e disparar quando o ponteiro do mouse está sobre a barra de rolagem quando você deseja rolar, mas não deseja acionar um evento mouseLeave sobre ele. Em document
vez disso, ative-o, como no exemplo.
Talvez se você estiver ouvindo OnMouseOver constantemente na tag do corpo, então callback quando o evento não estiver ocorrendo, mas, como Zack afirma, isso pode ser muito feio, porque nem todos os navegadores lidam com eventos da mesma maneira, há até alguns possibilidade de você perder o MouseOver mesmo por estar sobre um div na mesma página.
Talvez isso ajudasse alguns dos que viriam aqui mais tarde.
window.onblur
e document.mouseout
.
window.onblur
é acionado quando:
Ctrl+Tab
ou Cmd+Tab
.Basicamente, a qualquer momento que a guia do navegador perde o foco.
window.onblur = function(){
console.log("Focus Out!")
}
document.mouseout
é acionado quando:
Ctrl+Tab
ou Cmd+Tab
.Basicamente, em qualquer caso, quando o cursor sai do documento.
document.onmouseleave = function(){
console.log("Mouse Out!")
}
window.onblur
também. +1
$(window).mouseleave(function() {
alert('mouse leave');
});
Isso funcionou para mim. Uma combinação de algumas das respostas aqui. E eu incluí o código mostrando um modelo apenas uma vez. E o modelo desaparece quando clicado em qualquer outro lugar.
<script>
var leave = 0
//show modal when mouse off of page
$("html").mouseleave(function() {
//check for first time
if (leave < 1) {
modal.style.display = "block";
leave = leave + 1;
}
});
// Get the modal with id="id01"
var modal = document.getElementById('id01');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
var demo = document.getElementById('demo');
document.addEventListener("mouseout", function(e){demo.innerHTML="😞";});
document.addEventListener("mouseover", function(e){demo.innerHTML="😊";});
div { font-size:80vmin; position:absolute;
left:50%; top:50%; transform:translate(-50%,-50%); }
<div id='demo'>😐</div>