Переместить активный элемент теряет событие mouseout в Internet Explorer - PullRequest
13 голосов
/ 10 сентября 2010

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

Используемая мной библиотека имеет аккуратное решение, которое использует appendChildren на активном элементе, чтобы переместить его в конец своего родителя.так дальше к концу домена и, в свою очередь, сверху.

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

Я сократил функциональность, чтобы подтвердить проблему.Он отлично работает в Firefox, но не в любой версии IE.Я использую jquery здесь для скорости.Решения могут быть в простом старом javascript .. который будет предпочтительным, так как может потребоваться возврат в поток.

Я не могу использовать z-index здесь, так как элементы vml, библиотекаРафаэль, и я использую вызов toFront.Пример использования ul / li для демонстрации проблемы в простом примере

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="js/jquery.min.js" type="text/javascript"></script>
<style>
    li
    {
        border:1px solid black;
    }
</style>
</head>
<body>
<ul><li>Test 1</li></ul>
<ul><li>Test 2</li></ul>
<ul><li>Test 3</li></ul>
<ul><li>Test 4</li></ul>
<script>
$(function(){
    $("li").mouseover(function(){
        $(this).css("border-color","red");
        this.parentNode.appendChild(this);
    });

    $("li").mouseout(function(){
        $(this).css("border-color","black");
    });
});
</script>
</body>
</html>

Редактировать: Вот ссылка на js paste bin, чтобы увидеть ее в действии.http://jsbin.com/obesa4

** Изменить 2: ** См. Все комментарии на все ответы, прежде чем публиковать как можно больше информации в этом.

Ответы [ 4 ]

15 голосов
/ 24 октября 2010

Проблема в том, что IE обрабатывает mouseover по-разному , потому что он ведет себя как mouseenter и mousemove в сочетании с элементом. В других браузерах это просто mouseenter.

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

Решение состоит в том, чтобы эмулировать правильное поведение mouseover, чтобы действия в onmouseover выполнялись только один раз.

$("li").mouseover( function() {
    // make sure these actions are executed only once
    if ( this.style.borderColor != "red" ) {
        this.style.borderColor = "red";
        this.parentNode.appendChild(this);
    }
});

Примеры

  1. Ваше расширенное демо
  2. Пример , демонстрирующий разницу между браузерами mouseover (бонус: собственный JavaScript)
1 голос
/ 24 мая 2014

Я изменил ответ @galambalazs, потому что обнаружил, что он потерпит неудачу, если я действительно быстро наведусь на элементы li, так как некоторые элементы все равно сохранят эффект mouseover.

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

$(function(){

    // Track any hovered elements
    window.hovered = [];

    $("li").mouseover(function() {
        // make sure that these actions happen only once
        if ( $(this).css("border-color") != "red" ) {
            resetHovered ();  // Reset any previous hovered elements
            $(this).css("border-color","red");
            this.parentNode.appendChild(this);
            hovered.push(this);
        }
    });

    $("li").mouseout(function(){
        resetHovered();  // Reset any previous hovered elements
    });

    // Reset any elements on the stack
    function resetHovered () {
        while ( hovered.length > 0 ) {
            var elem = hovered.pop();
            $(elem).css("border-color","black");
        }
    }
});

Я тестировал это решение с IE 11. Функциональный пример можно найти здесь .

1 голос
/ 20 октября 2010

Мне удалось заставить его работать с вложенными элементами div и событием mouseenter для родителя:

<div id="frame">
  <div class='box'></div>
  <div class='box'></div>
  <div class='box'></div>
  <div class='box'></div>
</div>
...
$('#frame').mouseenter(function() {
     $(".box").css("border-color", "black");
});

Вот рабочая версия с использованием Raphael:

http://jsfiddle.net/xDREx/

0 голосов
/ 11 сентября 2010

Это шатко, и, похоже, только для IE (но так же, как и VML). Если для родительского элемента указана высота, вы можете прикрепить обработчик mouseout к родительскому элементу ... но, похоже, это не сработает в вашей ситуации. Лучшая альтернатива - использовать указатель мыши на соседних элементах, чтобы скрыть его:

$(function()
{
    $("li").mouseover(function()
    {
        $("li").css("border-color", "black");
        $(this).css("border-color", "red");
        this.parentNode.appendChild(this);
    });
});

Или SVG. Вы можете использовать z-index в SVG.

...