Question

Imaginez que j'ai les éléments suivants:

+------------------+
|                  |
|    +----------------+
|    |                |
|    |                |
|    +----------------+
|                  |
+------------------+

L'élément interne présente positionnement qui signifie qu'il peut rester visuellement à l'extérieur de son parent, et je mis un écouteur d'événement sur le parent comme par exemple:

parent.addEventListener('mouseover', function(e) {
  // log mouse is over me
}, false);

Si la souris I directement sur le parent du fond, je reçois un événement direct, mais à cause de l'événement de routage si la souris I au-dessus de la face (frapper l'enfant en premier), je vais aussi recevoir l'événement de l'enfant il bouillonne.

Si je continue à aller à gauche jusqu'à ce que je suis hors de l'élément enfant et dans l'espace parent, je vais un événement directement, si je vais à droite, je vais prendre un autre événement barboter de l'élément enfant.

est par la conception et le design est tout à fait bien, however- si je veux faire une simple action lorsque la souris me overs (y compris mes articles enfants), je dois faire un travail supplémentaire pour bloquer les événements que je ne suis pas intéressé par .. par exemple, cela fonctionnerait:

var isOver = false;

parent.addEventListener('mouseover', function(e) {
  if (isOver) return;
  isOver = true;
  // log mouse is over me
}, false);

parent.addEventListener('mouseout', function(e) {
  if (e.relatedTarget == this || e.relatedTarget.isDescendantOf(this)) return;
  isOver = false;
  // log mouse is leaving me
}, false);

Essentiellement, le code a une variable d'état pour déterminer si la souris a « overed » parent (soit par son enfant ou non), et si l'événement se déclenche à nouveau tandis que « overed » ces événements sont ignorés .. Nous saisissons aussi la souris sur l'événement et demander .. est le relatedTarget (la cible que vous êtes sur le point d'entrer) ME? (Le parent), ou un enfant éventuel de moi? si oui, alors ne faites rien .. sinon définir l'état « overed » false.

Alors que le code fonctionne réellement, mais imaginez que je ne peux pas utiliser la propriété relatedTarget pour déterminer la prochaine cible, comment feriez-vous de faire ce comportement?

J'espère que le bon sens, j'ai le sentiment Theres contexte ne suffit pas dans les événements de le faire sans relatedTarget mais a estimé qu'il pourrait bien être un angle en ce qui concerne le changement de comportement sur la propriété eventPhase (pour déterminer si l'événement est direct ou barboter ).

Aussi je ne cherche pas de réponses en disant « cela ne fonctionnera pas en savoir blah blah » .. Je travaille contre les navigateurs spec événement w3c ne en ce moment.

Merci d'avance, Stephen.


Modifier, juste pour clarifier, je veux que les événements se passer comme si j'ai un seul élément qui ressemblait à ceci (si l'élément était en fait comme ci-dessus par exemple):

+------------------+
|                  |
|                  +--+
|                     |
|                     |
|                  +--+
|                  |
+------------------+
Était-ce utile?

La solution

Je pense que ce que vous recherchez sont "mouseenter" événement (se déclenche lorsque l'utilisateur déplace le pointeur de la souris à l'intérieur des limites de l'objet) et http://jsbin.com/uputi (ajouter /edit à l'URL pour modifier le code source):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
<title>Sandbox</title> 
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<style type="text/css" media="screen"> 
#outer { width:200px; height:200px; border:1px solid #333; }
#inner { float:right; width:125px; height:80px; margin-right:-80px; border:1px solid #333; }
</style> 

<script> 
window.onload = function() {
  function mouseenter() {
    document.getElementById('dbg').innerHTML = 'mouse entered #outer boundary';
  }

  function mouseleave() {
    document.getElementById('dbg').innerHTML = 'mouse left #outer boundary';
  }

  var outer = document.getElementById('outer');

  if ('onmouseenter' in document.body) {
    // browser supports mouseenter/mouseleave natively (i.e., IE)
    outer.onmouseenter = mouseenter;
    outer.onmouseleave = mouseleave;
  }
  else {
    // simulate mouseenter/mouseleave in other browsers
    function wrap(fn) {
      return function(event) {
        var parent = event.relatedTarget;

        // Check if we're still within the same parent (traverse up parentNodes)
        while (parent && parent != this) {
          parent = parent.parentNode
        }

        if(parent != this) {
          // call the *real* mouseover/mouseout handler
          fn.call(this, event)
        }
      }
    }

    outer.onmouseover = wrap(mouseenter);
    outer.onmouseout = wrap(mouseleave);
  }
}
</script> 
</head> 
<body> 
  <div id="outer"> 
    <div><code>#outer</code></div> 
    <div>&nbsp;</div> 
    <div>&nbsp;</div> 
    <div id="inner"><code>#inner</code></div> 
  </div> 
  <div id="dbg"></div> 
</body> 
</html>

Il utilise relatedTarget comme vous le faites (qui fonctionne très bien dans les navigateurs standards Pour votre information), mais sans le drapeau de l'État. Voir ces requêtes apporte des événements fantastiques à d'autres navigateurs . (Note jQuery utilise la technique elle décrit en interne, avec quelques modifications mineures).

Prototype 1.6.1 a aussi ces événements simulé.

Autres conseils

Je pense que vous devez simplement stopPropagation

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top