2008-09-08 3 views
4

Я использую JavaScript, чтобы скрыть изображение и показать скрытый под ним текст. Но, когда текст отображается, если вы прокручиваете его, он запускает событие mouseout на контейнере, которое затем скрывает текст и снова показывает изображение, и оно просто переходит в странный цикл.Проблемы с событием 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; 

и добавить третий DIV в контейнере (должен быть последним ребенком контейнера) с:

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

и поймать MouseOver и события mouseout на этом div.

Поскольку у него нет дочерних элементов, вам не следует распространять на него ложные события мыши и мыши.

Edit:

То, что я считаю, бывает, что когда курсор перемещается от родительского элемента на дочерний элемент, событие MouseOut происходит на родительский элемент, и событие Mouseover происходит на дочернем элементе , Однако, если обработчик mouseover на дочернем элементе не поймает событие и не прекратит его распространение, родительский элемент также получит событие mouseover.

+0

Это также работает, если вы хотите сделать высоту DIV 100% от ее родительского элемента (то есть на боковой панели); хотя приведенное выше не будет полезно, если ваш «text1» DIV содержит любые якоря, поскольку им будет препятствовать дополнительный DIV. –

0

Это может быть не лучшее решение, но вы можете установить глобальную логическую переменную, которая была бы доступна для обоих методов, которые бы просто указали, было ли последнее действие HoverIn или HoverOut. Вы можете использовать эту логическую переменную, чтобы определить, должен ли код работать или нет.

if (bWasHoverIn){ 
    ... 
} 
0

Не должно ли событие onmouseover находиться на изображении div и событие onmouseout находиться в текстовом div?

0

@ Ryan Булевский не очень помогает, он просто избегает цикла, но событие mouseover все еще запущено, и текст становится скрытым.

@Brian Это было так, но оно вел себя одинаково.

0

Я не уверен, что это соответствовало бы остальной части вашего стиля, но, возможно, если вы изменили css на текстовый div, то он был того же размера, что и изображение, или зафиксировал размер внешнего 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 и использовать mouseenter и mouseleave с уверенностью.Обратите внимание, что я расширил проверку для выхода из окна или ввода XUL chrome; это, казалось, исправить некоторые случаи краев в Firefox для меня.

Смежные вопросы