Проблемы с событием mouseout - PullRequest
       24

Проблемы с событием mouseout

6 голосов
/ 08 сентября 2008

Я использую 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;
}

Это кажется очень простым, но я просто не могу обернуть голову вокруг него.

Ответы [ 6 ]

5 голосов
/ 08 сентября 2008

Я бы дал контейнеру div:

position: relative;

и добавьте третий div в контейнер (должен быть последним дочерним элементом контейнера) с помощью:

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

и вместо этого поймайте события mouseover и mouseout в этом div.

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

Edit:

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

4 голосов
/ 13 октября 2008

Похоже, что вы действительно хотите, это 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);

Как вариант, исправьте prototype.js и используйте mouseenter и mouseleave с уверенностью. Обратите внимание, что я расширил проверку для выхода из окна или ввода XUL Chrome; казалось, это исправило некоторые крайние случаи в Firefox для меня.

0 голосов
/ 08 сентября 2008

Я не уверен, что это будет соответствовать остальной части вашего стиля, но, возможно, если вы изменили CSS на div текста, чтобы он был такого же размера, как изображение, или зафиксировали размер внешнего div, то когда срабатывает событие mouseover, размер внешнего элемента div не изменяется настолько, чтобы вызвать событие mouseout.

Имеет ли это смысл?

0 голосов
/ 08 сентября 2008

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

@ Брайан Это было так, но вело себя так же.

0 голосов
/ 08 сентября 2008

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

0 голосов
/ 08 сентября 2008

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

if (bWasHoverIn){
   ...
}
...