Перемещение активного элемента теряет событие 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: ** Просмотреть все комментарии по всем ответам перед публикацией, поскольку в них больше информации.
Ответы
Ответ 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. Функциональный пример можно найти здесь.