Événement Javascript lorsque la souris quitte la fenêtre du navigateur [dupliquer]

cette question a déjà une réponse ici:

  • Comment puis-je détecter quand la souris quitte la fenêtre? 16 réponses

j'aimerais qu'un code Javascript s'exécute lorsque la souris quitte la fenêtre du navigateur. J'ai seulement besoin de prendre en charge Safari (WebKit.)

j'ai essayé mettre un mouseout gestionnaire de fenêtre. Ce gestionnaire est appelé de façon fiable lorsque la souris quitte la fenêtre du navigateur. Mais à cause du barbotage, il est aussi appelé lorsque la souris se déplace entre les éléments du document. Je n'arrive pas à déterminer quand la souris a réellement quitté la fenêtre et quand elle n'a bougé qu'entre les éléments.

lorsque la souris quitte la fenêtre, exactement un événement est généré, et l'élément cible semble être l'élément que la souris était en fait plus. Donc vérifier si l'élément cible est fenêtre ou document ne fonctionne pas. Et envelopper toute la page dans un div invisible contenant ne fonctionne pas non plus: si le div est invisible, alors la souris ne sera jamais dessus, donc rien ne change.

(la même chose se produit si je mets le handler sur document ou document.corps, sauf ce document surprenant.corps n'a pas mouseover/mouseout événements lorsque la souris entre ou quitte une partie vide de la fenêtre, comme espace vertical vide créé par positionnement absolu d'un élément avec fond:0. Pour cet espace, document et window obtiendront des évènements mouseover/mouseout avec la cible , mais document.le corps ne sera pas.)

Quelques idées que j'ai eu:

  • sur chaque événement mouseout, obtenez la position réelle de la souris et voyez si elle est en fait au-dessus de la fenêtre. Mais je ne sais pas si c'est vraiment possible et il semble que ce serait délicat de éliminer toutes les conditions de course.
  • également enregistrer un mouseover handler et de détecter les cas où mouseout n'est pas procédé par (ou suivi peu de temps par a) un mouseover. Mais qui aurait besoin d'une minuterie.

nous utilisons un prototype.js donc idéalement je voudrais exprimer la solution en termes d'événement de prototype.observez, mais je peux comprendre cette partie.

Merci pour toutes les suggestions!

11
demandé sur Rob W 2009-11-04 10:13:07

7 réponses

résumé: ceci peut être fait proprement en vérifiant la propriété relatedTarget pendant l'événement mouseout. Si relatedTarget n'est pas un enfant de document, alors la souris vient de quitter la fenêtre. C'est facile à faire soi-même, mais si vous ne le voulez pas, certaines bibliothèques (Mootools, future Prototype..) sont dotés d'une fonctionnalité d'intégration, et d'autres (Prototype actuel) ont des extensions disponibles. Sur IE, vous pouvez à la place utiliser mouseleave, qui est une version sans bulles de mouseout.

détails:

IE a des événements appelés mouseenter et mouseleave qui sont des versions non-bouillonnantes de mouseover et mouseout. D'autres navigateurs ne le font pas, mais s'ils le faisaient, configurer un écouteur de mouseleave sur window ou document ferait l'affaire.

un gentleman nommé Ken Snyder vient à la rescousse:

sur un mouseover, la cible relatée la propriété renvoie au noeud de lequel le pointeur est venu. Sur un mouseout, les références de propriété relatedTarget le nœud vers lequel le pointeur est allé.Sur en tout cas, le scope est le noeud à l'événement est attaché.Lorsque l' relatedTarget est pas un enfant de la cible actuelle, un événement souriant est l'équivalent d'un événement mouseenter et un l'événement mouseout est équivalent à un événement de mouseleave.

-- http://kendsnyder.com/archives/6-MouseEnter-and-MouseLeave.html

cela permet d'implémenter mouseenter et mouseleave dans d'autres navigateurs. En fait, Ken fournit le même code Prototype pour le faire: http://kendsnyder.com/sandbox/enterleave/MouseEnterLeave.js

Duroth a souligné dans ses commentaires que MooTools inclut déjà quelque chose de similaire. (Merci Duroth. On dirait que la prochaine version du Prototype (1.6.2) pourrait inclure cette fonctionnalité, mais je ne trouve rien de définitif.

12
répondu Geoff 2009-11-05 09:43:47

utilisant uniquement javascript, pas de prototype 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">&nbsp;</div>
<div style="width:300px; height: 200px; background: red;">Dummy element</div>
</body>
</html>

mise à JOUR:

Ajout d'un contrôle de la position de la souris sur mouseout déclenché lors du déplacement des éléments à l'intérieur et à l'extérieur du corps. S'il est dans la fenêtre, l'événement mouseout n'est pas déclenché.

Introduit également un drapeau pour l'état actuel de la souris "in" ou " out "en utilisant mouseIsIn . Si elle est true , mouseover ne sera pas déclencher trop.

9
répondu o.k.w 2009-11-04 08:12:53

peut-être Pouvez-vous définir un auditeur pour mouseover et mouseout document , body ou un autre élément qui enveloppe le document entier, et utiliser cela (en sauvegardant que c'est arrivé) comme un déclencheur pour déterminer si c'est une mouseout valide sur la fenêtre?

à défaut, votre première idée (concernant la vérification du poste) devrait plutôt bien fonctionner. N'importe quel événement passe le long du X/Y l'événement s'est produit. Si elle est quelque chose plus loin que la hauteur / largeur de la fenêtre, vous avez laissé le fenêtre réelle. Si elle est négative quoi que ce soit, vous de la gauche de la fenêtre. Et, peut-être, si c'est exactement la hauteur/largeur ou exactement le haut: 0 ou à gauche: 0, alors vous avez quitté la fenêtre.

1
répondu Kevin Peno 2009-11-04 07:46:00

quand la souris quitte n'importe quel élément, y compris la fenêtre, l'objet de fenêtre lancera un événement mouseout et passera l'objet event avec lui.

un des éléments de l'objet event est appelé toElement , qui est un pointeur vers l'élément que la souris vient d'entrer quand elle a quitté l'ancien. Mais quand la souris sort de la fenêtre, il n'y a pas de toElement donc cet article devient null .

en testant si Non cet article est null sur un événement mouseout , vous pouvez dire si la souris a quitté la fenêtre. Voici le code:

window.onmouseout=function(event){ 
  if(event.toElement===null) console.log('the mouse left the window'); 
}
1
répondu jaya 2014-05-10 02:27:39

votre problème vient des événements mouseout étant générés pour les éléments à l'intérieur de la fenêtre, qui puis bulle comme décrit dans le W3C événements spec . Vous pouvez vérifier sur quel élément l'événement a réellement été déclenché:

function mouseoutFunction(event) {
  event = event || window.event;
  var sender = event.srcElement || event.target;
}
0
répondu Gareth 2009-11-04 07:48:35

Voici ma solution basée sur une minuterie. Le timer ici est essentiellement utilisé pour donner une chance à d'autres gestionnaires d'événements (spécifiquement, onmouseover) d'exécuter avant de décider que la mosue est hors de la fenêtre. Le temps d'arrêt de 1ms (en fait autour de 33ms, il y a une résolution minimum de minuterie) donne un peu de temps pour que la mouseover se produise si elle ne l'a pas déjà fait.

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)
   }
}
0
répondu Raze 2009-11-04 09:48:45

vous pouvez utiliser onmouseout événement sur une fenêtre à la place

-1
répondu DVK 2009-11-04 07:19:49