web-dev-qa-db-fra.com

Comment puis-je détecter le moment où la souris quitte la fenêtre?

Je veux pouvoir détecter le moment où la souris quitte la fenêtre pour pouvoir empêcher les événements de se déclencher lorsque la souris de l'utilisateur est ailleurs.

Des idées sur la façon de faire cela?

74
Matt

Ce type de comportement est généralement souhaité lors de la mise en œuvre d'un comportement de glisser-déposer sur une page html. La solution ci-dessous a été testée sur IE 8.0.6, FireFox 3.6.6, Opera 10.53 et Safari 4 sur un ordinateur MS Windows XP.
D'abord une petite fonction de Peter-Paul Koch; gestionnaire d'événements inter-navigateurs:

function addEvent(obj, evt, fn) {
    if (obj.addEventListener) {
        obj.addEventListener(evt, fn, false);
    }
    else if (obj.attachEvent) {
        obj.attachEvent("on" + evt, fn);
    }
}

Et ensuite, utilisez cette méthode pour attacher un gestionnaire d'événements à l'événement mouseout des objets de document:

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");
    }
});

Enfin, voici une page HTML avec le script incorporé pour le débogage:

<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>
91
J Mills

Si vous utilisez jQuery, qu’en est-il de ce code court et attrayant -

$(document).mouseleave(function () {
    console.log('out');
});

Cet événement se déclenchera chaque fois que la souris ne sera pas dans votre page comme vous le souhaitez. Il suffit de changer la fonction pour faire ce que vous voulez.

Et vous pouvez aussi utiliser:

$(document).mouseenter(function () {
    console.log('in');
});

Pour déclencher lorsque la souris revient à la page.

Source: https://stackoverflow.com/a/16029966/895724

37
Mandeep Janjua

Cela fonctionne pour moi:

addEvent(document, 'mouseout', function(evt) {
  if (evt.toElement == null && evt.relatedTarget == null) {
    alert("left window");
  }
});
24
user1084282

Pour détecter la suppression de la souris sans tenir compte de la barre de défilement et du champ de saisie semi-automatique, ni inspecter:

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");

  }
});

Explications des conditions:

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
6
Daphoque

Aucune de ces réponses n'a fonctionné pour moi. J'utilise maintenant:

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');
    }

});

J'utilise ceci pour un widget de téléchargement de fichier par glisser-déposer. Ce n'est pas tout à fait précis, étant déclenché lorsque la souris se trouve à une certaine distance du bord de la fenêtre.

5
Emmanuel

Je reprends ce que j'ai dit. C'est possible. J'ai écrit ce code, fonctionne parfaitement.

window.onload = function() {

    $span = document.getElementById('text');

    window.onmouseout = function() {
        $span.innerHTML = "mouse out";  
    }

    window.onmousemove = function() {
        $span.innerHTML = "mouse in";   
    }

}

fonctionne en chrome, firefox, opéra. Aint testé dans IE mais supposons que cela fonctionne.

modifier. IE comme toujours cause des problèmes. Pour que cela fonctionne dans IE, remplacez les événements de window à documenter:

window.onload = function() {

    $span = document.getElementById('text');

    document.onmousemove = function() {
        $span.innerHTML = "mouse move";
    }

    document.onmouseout = function() {
        $span.innerHTML = "mouse out";
    }

}

combinez-les pour la détection du curseur kick ass crossbrowser o0: P

3
Ozzy

J'ai essayé tout ce qui précède, mais rien ne semble fonctionner comme prévu. Après quelques recherches, j’ai trouvé que e.relatedTarget est le html just avant que la souris ne quitte la fenêtre .

Alors ... j'ai fini avec ça:

document.body.addEventListener('mouseout', function(e) {
    if(e.relatedTarget === document.querySelector('html')) {
        console.log('We\'re OUT !');
    }
});

S'il vous plaît laissez-moi savoir si vous trouvez des problèmes ou des améliorations!

2
Symba

L'utilisation de l'événement onMouseLeave empêche la formation de bulles et vous permet de détecter facilement le moment où la souris quitte la fenêtre du navigateur.

<html onmouseleave="alert('You left!')"></html>

http://www.w3schools.com/jsref/event_onmouseleave.asp

2
Samy Bencherif
$(window).mouseleave(function() {
 alert('mouse leave');
});
1
sandeep kumar

Peut-être que si vous écoutez constamment OnMouseOver dans la balise body, rappelez-le lorsque l'événement ne se produit pas, mais, comme le dit Zack, cela pourrait être très laid, car tous les navigateurs ne gèrent pas les événements de la même manière possibilité que vous perdiez le MouseOver même en étant sur une div dans la même page.

1
Pablo Albornoz

appliquer ce css:

html
{
height:100%;
}

Cela garantit que l’élément html occupe toute la hauteur de la fenêtre.

appliquer cette jquery:

$("html").mouseleave(function(){
 alert('mouse out');
});

Le problème avec mouseover et mouseout est que si vous passez le curseur de la souris sur un élément enfant, cela déclenchera l'événement. La fonction que j'ai donnéen'est pasdésactivée lorsque vous passez la souris sur un élément enfant. Il est uniquement activé lorsque vous passez la souris dans/hors de la fenêtre

juste pour que vous sachiez que vous pouvez le faire lorsque l'utilisateur affiche la souris dans la fenêtre:

$("html").mouseenter(function(){
  alert('mouse enter');
});
1
www139
$(window).mouseleave(function(event) {
  if (event.toElement == null) {
    //Do something
  }
})

Cela peut sembler un peu compliqué mais il ne se déclenchera que lorsque la souris quittera la fenêtre. Je n'arrêtais pas d'attraper des événements d'enfants et cela le résolvait

1
Cekaleek

Peut-être que cela aiderait certains de ceux qui viendront ici plus tard .window.onblur et document.mouseout.

window.onblur est déclenché lorsque:

  • Vous passez à une autre fenêtre en utilisant Ctrl+Tab ou Cmd+Tab.
  • Vous vous concentrez (pas seulement au survol) sur l'inspecteur de documents.
  • Vous changez de bureau.

Fondamentalement, chaque fois que cet onglet de navigateur perd le focus.

window.onblur = function(){
    console.log("Focus Out!")
}

document.mouseout est déclenché lorsque:

  • Vous déplacez le curseur sur la barre de titre.
  • Vous passez à une autre fenêtre en utilisant Ctrl+Tab ou Cmd+Tab.
  • Vous ouvrez déplacez le curseur sur l'inspecteur de document.

En gros, dans tous les cas, lorsque votre curseur quitte le document.

document.onmouseleave = function(){
    console.log("Mouse Out!")
}
0
Jayant Bhawal

Je n'ai pas testé cela, mais mon instinct serait de faire un appel de fonction OnMouseOut sur la balise body.

0
Ender

Cela a fonctionné pour moi. Une combinaison de certaines des réponses ici. Et j'ai inclus le code montrant un modèle une seule fois. Et le modèle disparaît lorsqu'on clique ailleurs.

<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>
0
Morgan Hayes

J'ai essayé l'un après l'autre et j'ai trouvé la réponse acceptée abowe qui fonctionne réellement !

https://stackoverflow.com/a/3187524/985399

Je saute les anciens navigateurs, j'ai donc raccourci le code pour que je puisse utiliser les navigateurs modernes IE9 +:

    document.addEventListener("mouseout", function(e) {
        let t = e.relatedTarget || e.toElement;
        if (!t || t.nodeName == "HTML") {
          console.log("left window");
        }
    });

Ici vous voyez le support du navigateur

Mais "mouseout" déclenche sur tous les éléments du document . Le code empêche que cela se produise est éliminé par mouseleave (lien IE5.5 + se).

Le code suivant fonctionne à la fois sur en laissant la souris et en en faisant glisser le document en dehors du document. :

var x = 0

document.onmouseleave = function(e) { console.log(x++) }

N'ayez pas l'événement sur document.body parce que la barre de défilement de Windows peut le réduire et déclencher le défilement.

0