Подтвердить что ты не робот

Перемещение активного элемента теряет событие mouseout в Internet Explorer

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

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

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

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

Я не могу использовать z-index здесь, так как элементы vml, библиотека Raphael, и я использую вызов 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, чтобы увидеть ее в действии. http://jsbin.com/obesa4

** Редактировать 2: ** Просмотреть все комментарии по всем ответам перед публикацией, поскольку в них больше информации.

4b9b3361

Ответ 1

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

Таким образом, даже после того, как ваша мышь ввела целевой элемент, и вы изменили его, посмотрите и снова вернетесь к нему. parent 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);
    }
});

<сильные > Примеры

Ответ 2

Мне удалось заставить его работать с вложенными 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/

Ответ 3

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

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

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

Ответ 4

Я изменил ответ @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. Функциональный пример можно найти здесь.