2008-09-08 38 views
4

我正在使用JavaScript來隱藏圖像並顯示隱藏在其下的一些文本。但是,如果在滾動顯示文本時顯示文本,它會觸發容器上的鼠標移出事件,然後隱藏文本並再次顯示圖像,並且它會進入一個奇怪的循環。mouseout事件的問題

的HTML如下:

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

和JavaScript(它使用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; 
} 

這看起來很簡單,但我只是不能換我的頭周圍。

回答

4

我給div容器:

position: relative; 

,並在容器中添加第三個格(應該是容器的最後一個子)與:

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

,趕上鼠標懸停而不是在這個div上的鼠標事件。

因爲它沒有子元素,所以不應該讓spurious mouseover和mouseout事件傳播給它。

編輯:

我相信情況是,當從父元素光標移動到一個子元素,mouseOut事件發生的父元素,和鼠標懸停事件的子元素上發生。但是,如果子元素上的mouseover處理程序不捕獲事件並停止傳播,則父元素也將收到mouseover事件。

+0

這也適用於你想讓DIV的高度達到其父母的100%(即在側邊欄中);儘管如上所述,如果你的「text1」DIV包含任何錨,因爲它們將被額外的DIV阻擋。 – 2009-07-21 20:04:15

0

這可能不是最好的解決方案,但您可以設置一個全局布爾變量,這兩個方法都可以訪問,只需指定最後一個操作是HoverIn還是HoverOut。你可以使用這個布爾變量來確定代碼是否應該運行。

if (bWasHoverIn){ 
    ... 
} 
0

不應該onmouseover事件在圖像div和onmouseout事件是在文本div?

0

@Ryan布爾沒有真正的幫助,它只是避免了循環,但mouseover事件仍然被觸發,文本被隱藏。

@布萊恩它曾經是這樣,但它表現相同的方式。

0

我不確定這是否適合您的其他樣式,但如果您更改了文本div上的css使其與圖片大小相同,或者固定了外部div的大小,那麼當mouseover事件觸發時,外部div的大小不會變化太多以至於導致mouseout事件。

這是否有意義?

4

這聽起來像你真正想要的是mouseenter/mouseleave(IE專有的事件,但容易模仿):

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

另外,patch prototype.js和使用mouseentermouseleave有信心。請注意,我已經擴展了離開窗口或進入XUL chrome的檢查;這似乎解決了Firefox中的一些邊緣情況。