2010-09-10 3 views
10

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

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

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

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

Я не могу использовать z-index здесь, поскольку элементы vml, библиотека Raphael, и я использую вызов toFront. Пример использования уль/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> 

Edit: Вот ссылка на JS пасты бункером, чтобы увидеть его в действии. http://jsbin.com/obesa4

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

+0

Я не могу понять ваше сообщение. вы хотите, чтобы событие mouseout не срабатывало, пока мышь все еще находится над элементом? каков ваш реальный вопрос? – lincolnk

+0

И для этого.parentNode.appendChild (this) ;, вы пытаетесь повторно добавить существующий элемент LI? Почему бы просто не добавить к нему класс CSS вместо добавления/удаления одного и того же элемента с новым CSS? Или ваш исходный код включает в себя добавление совершенно нового элемента из другого места в UL, чтобы подражать вашему «расширенному» размеру эффекта, который вы упомянули в начале? – Gary

+0

Linkol Я пытаюсь заставить образец кода работать, т. Е. Как в Firefox. Событие mouseout не срабатывает. В качестве примера я использую элементы li. Как я уже сказал в своем посте, элементы на самом деле являются элементами VML. Таким образом, такие вещи, как z-index или add classes, не будут работать, если только люди не могут оказаться разными. – johnwards

ответ

12

Проблема заключается в том, что 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. Extented demo of yours
  2. Example демонстрирует разницу mouseover между браузерами (бонус: родной Javascript)
+0

Блестящий, именно то, на что я надеялся, когда я поставил бонус. Мой код работает намного лучше, теперь мне тоже не придется его обманывать. – johnwards

+0

Я gald Я мог бы помочь :) – galambalazs

+3

Вот простой пример в Raphael 2.0.2 http://jsfiddle.net/K2bSY/2/ для людей, сталкивающихся с одной и той же проблемой, используя toFront(), показывая пример исправить, используя Raphael's. data() – user568458

0

Это неудобно, и, похоже, 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.

+0

Хмм, альтернатива я думаю, решение здесь. В принципе, мне нужно будет вызвать функцию сброса для всех остальных элементов на мыши, которые будут запускать анимацию сжатия. Это очень неуклюже, но это может сработать. Я сейчас проголосую за этот ответ и посмотрю, сможет ли кто-нибудь еще что-нибудь придумать. – johnwards

1

я смог получить его работу с вложенной дивой и событиями 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"); 
}); 

Вот рабочая версия, использующая Рафаэль:

http://jsfiddle.net/xDREx/

+0

Может ли это заставить работать. Ничего не происходит, когда я курсирую над коробками. – johnwards

+0

Пробовали ли вы ссылку? Какой браузер вы используете? Я получил его для работы в IE6, IE7 и IE8. – webXL

+0

Ooh mouseenter на родительском, это в основном то, что вы делаете. Сработает сброс. Ницца. Однако он не решает основной проблемы потерянных событий. (Нажмите событие тоже!) Деффо стоит пополам 200 очков. Если бы я мог получить элемент, чтобы добраться до вершины без проигравших событий, я был бы счастливым человеком. (JSFiddle, должно быть, не работает, теперь отлично работает) – johnwards

0

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

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

  • Нет связанных вопросов^_^