Domanda

Sto utilizzando JavaScript per nascondere un'immagine e mostrare del testo nascosto sotto di essa.Ma, quando il testo viene mostrato se lo scorri sopra, attiva l'evento mouseout sul contenitore, che quindi nasconde il testo e mostra di nuovo l'immagine, e entra in uno strano ciclo.

L'HTML è simile a questo:

<div onmouseover="jsHoverIn('1')"
     onmouseout="jsHoverOut('1')">
    <div id="image1" />
    <div id="text1" style="display: none;">
        <p>some content</p>
        <p>some more content</p>
    </div>
</div>

E il javascript (utilizza scriptaculous):

function jsHoverIn(id) {
  if(!visible[id]) {
    new Effect.Fade ("image" + id, {queue: { position: 'end', scope: id } });
    new Effect.Appear ("text" + id, {queue: { position: 'end', scope: id } });
    visible[id] = true;
  }
}
function jsHoverOut (id) {
  var scope = Effect.Queues.get(id);
  scope.each(function(effect) { effect.cancel(); });

  new Effect.Fade ("text" + id, {queue: { position: 'end', scope: id } });
  new Effect.Appear ("image" + id, {queue: { position: 'end', scope: id } });
  visible[id] = false;
}

Sembra davvero semplice, ma non riesco proprio a capirlo.

È stato utile?

Soluzione

Darei il div contenitore:

position: relative;

e aggiungi un terzo div nel contenitore (dovrebbe essere l'ultimo figlio del contenitore) con:

position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;

e cattura invece gli eventi mouseover e mouseout su questo div.

Poiché non ha elementi figlio, non dovrebbero verificarsi eventi di mouseover e mouseout spuri che si propagano ad esso.

Modificare:

Quello che credo accada è che quando il cursore si sposta da un elemento genitore a un elemento figlio, si verifica un evento mouseout sull'elemento genitore e un evento mouseover sull'elemento figlio.Tuttavia, se il gestore del mouseover sull'elemento figlio non rileva l'evento e ne interrompe la propagazione, anche l'elemento genitore riceverà l'evento mouseover.

Altri suggerimenti

Sembra che quello che vuoi veramente sia mouseenter/mouseleave (Eventi proprietari di IE, ma facili da emulare):

// Observe mouseEnterLeave on mouseover/mouseout
var mouseEnterLeave = function(e) {
    var rel = e.relatedTarget, cur = e.currentTarget;
    if (rel && rel.nodeType == 3) {
        rel = rel.parentNode;
    }
    if(
        // Outside window
        rel == undefined ||
        // Firefox/other XUL app chrome
        (rel.tagName && rel.tagName.match(/^xul\:/i)) ||
        // Some external element
        (rel && rel != cur && rel.descendantOf && !rel.descendantOf(cur))
    ) {
        e.currentTarget.fire('mouse:' + this, e);
        return;
    }
};
$(yourDiv).observe('mouseover', mouseEnterLeave.bind('enter'));
$(yourDiv).observe('mouseout', mouseEnterLeave.bind('leave'));

// Use mouse:enter and mouse:leave for your events
$(yourDiv).observe(!!Prototype.Browser.IE ? 'mouseenter' : 'mouse:enter', yourObserver);
$(yourDiv).observe(!!Prototype.Browser.IE ? 'mouseleave' : 'mouse:leave', yourObserver);

In alternativa, patch prototipo.js e utilizzare mouseenter E mouseleave con fiducia.Tieni presente che ho ampliato il controllo per uscire dalla finestra o accedere a XUL Chrome;questo mi è sembrato risolvere alcuni casi limite in Firefox.

Questa potrebbe non essere la soluzione migliore, ma potresti impostare una variabile booleana globale che sia accessibile a entrambi i metodi e che specifichi semplicemente se l'ultima azione è stata HoverIn o HoverOut.Potresti usare questa variabile booleana per determinare se il codice deve essere eseguito o meno.

if (bWasHoverIn){
   ...
}

L'evento onmouseover non dovrebbe essere sul div immagine e l'evento onmouseout sul div testo?

@Ryan Il valore booleano non aiuta molto, evita semplicemente il ciclo, ma l'evento del passaggio del mouse viene comunque attivato e il testo viene nascosto.

@Brian Una volta era così, ma si comportava allo stesso modo.

Non sono sicuro che questo si adatterebbe al resto del tuo stile, ma forse se cambiassi il CSS sul div di testo in modo che avesse la stessa dimensione dell'immagine, o fissassi la dimensione del div esterno, quindi al passaggio del mouse evento attivato, la dimensione del div esterno non cambierebbe così tanto da causare l'evento mouseout.

Ha senso ciò?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top