2008-09-08 8 views
4

Ich benutze JavaScript, um ein Bild zu verstecken und etwas Text zu zeigen, der unter ihm versteckt ist. Wenn der Text jedoch angezeigt wird, wenn Sie darüber blättern, wird das mouseout-Ereignis auf dem Container ausgelöst, das den Text dann ausblendet und das Bild erneut anzeigt, und es wird nur eine seltsame Schleife angezeigt.Probleme mit mouseout Ereignis

Die html sieht wie folgt aus:

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

Und das Javascript (Es verwendet 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; 
} 

Dies scheint wirklich einfach, aber ich kann nicht wickeln nur meinen Kopf um ihn herum.

Antwort

4

würde ich die div-Container geben:

position: relative; 

und ein drittes div im Container hinzufügen (sollte das letzte Kind des Behälters sein) mit:

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

und die Mouseover fangen und mouseout Ereignisse auf diesem div stattdessen.

Weil es keine untergeordneten Elemente hat, sollten Sie keine falschen Mouseover- und Mouseout-Ereignisse erhalten, die sich darauf ausbreiten.

Edit:

Was glaube ich, passiert ist, dass, wenn der Cursor bewegt sich von einem übergeordneten Element auf ein untergeordnetes Element, ein mouseout Ereignis tritt auf dem Mutterelement und ein Mouseover-Ereignis tritt auf das Kind-Element . Wenn jedoch der mouseover-Handler für das untergeordnete Element das Ereignis nicht abfängt und es nicht weitergibt, erhält das übergeordnete Element auch das mouseover-Ereignis.

+0

Dies funktioniert auch im Fall, dass Sie die DIV Höhe 100% seiner Eltern machen (das heißt in einem Kasten); obwohl das oben genannte nicht nützlich ist, wenn dein "text1" DIV irgendwelche Anker enthält, da diese durch das zusätzliche DIV blockiert werden. –

0

Dies ist möglicherweise nicht die beste Lösung, aber Sie könnten eine globale boolesche Variable festlegen, auf die beide Methoden zugreifen können, die nur angeben würde, ob die letzte Aktion HoverIn oder HoverOut war. Sie können diese boolesche Variable verwenden, um festzustellen, ob der Code ausgeführt werden soll oder nicht.

0

Sollte das Ereignis onmouseover nicht auf dem Bild div und das Ereignis onmouseout auf dem Text div sein?

0

@Ryan Die boolean hilft nicht wirklich, es vermeidet nur die Schleife, aber das mouseover Ereignis wird noch gefeuert und der Text wird hiden.

@Brian Früher war es so, aber es verhielt sich genauso.

0

Ich bin mir nicht sicher, ob dies mit dem Rest Ihres Stylings zusammenpasst, aber vielleicht, wenn Sie die CSS im Text div so geändert haben, dass es dieselbe Größe wie das Bild hat, oder die Größe des äußeren div, Wenn dann das mouseover-Ereignis ausgelöst wird, ändert sich die Größe des äußeren div nicht so stark, dass das mouseout-Ereignis ausgelöst wird.

Macht das Sinn?

4

Es klingt wie das, was Sie wirklich wollen, ist mouseenter/mouseleave (IE Eigenveranstaltungen, aber leicht zu emulieren):

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

Alternativ patch prototype.js und verwenden mouseenter und mouseleave mit Zuversicht entgegen.Beachten Sie, dass ich die Überprüfung für das Verlassen des Fensters oder die Eingabe von XUL chrome erweitert habe. Dies schien einige Randfälle in Firefox für mich zu beheben.