Mouseleave на контейнере с выделенным - Internet Explorer 10

Я подключил событие mouseleave и mouseenter к контейнеру. Этот контейнер содержит выбранный и некоторый случайный текст, я пропускаю указатель мыши над контейнером, а затем выбираю select, вот что происходит в Chrome vs IE 10:

Chrome: mouseleave не запускается (это то, что я хочу) введите описание изображения здесь

IE 10: mouseleave запускается (плохо, плохо) введите описание изображения здесь

Демо можно найти здесь

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

Ответы

Ответ 1

Я боюсь, что идеальное кросс-браузерное решение невозможно с тегом <select>, потому что браузеры и их версии отличаются при рендеринге опций. Некоторые из них используют собственный немаркируемый графический интерфейс и другие элементы HTML. Лучшее, что вы можете сделать в этом случае, - это настраиваемое раскрывающееся меню со скрытым вводом.

BTW. в этом случае mouseenter/mouseleave имеет лучшее поведение и предотвращает барботирование по сравнению с mouseover/mouseout

Ответ 2

Я добавил немного больше javascript, чтобы найти решение, хотя оно может и не быть идеальным для общего использования.

Единственное странное поведение, которое я могу найти, это то, что в IE он не учитывает значение, которое было изменено при нажатии, пока элемент select не будет размытым.

HTML

<div id="parent">
  <div>fdgfd</div>
  <div>content</div>
  <select name="" id="selectId">
    <option value="">1</option>
    <option value="">2</option>
    <option value="">3</option>
    <option value="">4</option>
    <option value="">5</option>
  </select>
</div>
<div id="result">out</div>

Javascript

var selected = false;
var toExit = false;

function blur() {
  selected = false;
  if (toExit) { 
    document.getElementById('result').innerHTML = 'out'
    toExit = false;
  }
}

document.getElementById('parent')
  .addEventListener('mouseleave', function() {
    // Store the exit so it can be used after blur
    toExit = true;
    if (!selected) {
      document.getElementById('result').innerHTML = 'out'
    }

});
document.getElementById('parent')
  .addEventListener('mouseenter', function() {
    toExit = false;
    return document.getElementById('result').innerHTML = 'in'
});

// Controls the selected state
document.getElementById('selectId')
  .addEventListener('blur', blur);

document.getElementById('selectId')
  .addEventListener('change', blur);

document.getElementById('selectId')
  .addEventListener('focus', function() {
    selected = true;
});

Ответ 3

Это может помочь, кажется, это работает при первом открытии раскрывающегося списка.

document.getElementById('idforselect')
  .addEventListener('mouseout', function(e) {
  e.stopPropagation();
});

Ответ 4

К сожалению, невозможно, чтобы поведение событий mouseleave не отображалось в браузерах одинаково. Это зависит от конкретной реализации браузера.

Он работает в соответствии с документацией IE.

mouseleave | событие onmouseleave

Запускается, когда пользователь перемещает указатель мыши за пределы объект.

Тот же эффект может быть достигнут с использованием дополнительного кода javascript, который будет обрабатывать события, инициируемые дочерними объектами.

Пожалуйста, проверьте пример.

Я добавил некоторые вспомогательные переменные и обработчики для событий focus/blur на объекте <select>.

var isSelectFocussed=false;
var inside = false;

function onMouseOut() {
   !isSelectFocussed && (document.getElementById('result').innerHTML = 'out');
}

document.getElementById('parent')
  .addEventListener('mouseleave', function() {
  onMouseOut();  
  inside = false;
})
document.getElementById('parent')
  .addEventListener('mouseover', function() {
  document.getElementById('result').innerHTML = 'in';
  inside = true;
});
document.querySelector('select')
 .addEventListener('focus', function() {
  isSelectFocussed = true;
});
document.querySelector('select')
 .addEventListener('blur', function() {
  isSelectFocussed = false;
  !inside && onMouseOut();
});

В любом случае, возможно, будет проще использовать настраиваемое раскрывающееся меню со скрытым <input>.