Internet Explorer и проблема с тегом <select> - PullRequest
8 голосов
/ 06 августа 2009

У меня возникла следующая проблема в Internet Explorer 7/8:

У меня есть всплывающее окно, которое активируется, когда пользователь наводит указатель мыши на ссылку. Всплывающее окно представляет собой простой <div>, который содержит некоторые данные. Внутри этого тега <div> есть тег <select> с некоторыми <option> с. Я прикрепил события mouseover / mouseout к <div>, чтобы это всплывающее окно оставалось открытым, пока курсор находится над ним. Проблема возникает, когда вы нажимаете на <select>, а затем наводите курсор на любой из <option> s. Это вызывает событие mouseout тега <div> и соответственно закрывает его.

Как я могу предотвратить закрытие всплывающего окна в IE?

Ответы [ 13 ]

9 голосов
/ 11 августа 2009

Вы должны быть в состоянии определить, является ли ситуация той, которая вам нужна, только со значениями вне события. Это немного запутанно, но, кажется, работает.

В обработчике событий вашего внешнего div сделайте что-то вроде этого:

<div onmouseover="if (isReal()) { toggle(); }"
     onmouseout="if (isReal()) { toggle(); }">
</div>

Затем реализуйте метод isReal:

function isReal() {
    var evt = window.event;
    if (!evt) {
        return true;
    }

    var el;
    if (evt.type === "mouseout") {
        el = evt.toElement;
    } else if (evt.type === "mouseover") {
        el = evt.fromElement;
    }
    if (!el) {
        return false;
    }
    while (el) {
        if (el === evt.srcElement) {
            return false;
        }
        el = el.parentNode;
    }
    return true;
}

По сути, метод isReal просто обнаруживает, произошло ли событие внутри div. Если это так, то он возвращает false, что позволяет избежать вызова переключателя скрытия.

2 голосов
/ 06 августа 2009

Мое предложение было бы установить другой флаг, когда поле выбора имеет фокус. Не закрывайте div, пока установлен флаг.

0 голосов
/ 15 августа 2009

Вы должны использовать event.stopPropagation() в <select> или cancelBubble() в <select> самом элементе.

0 голосов
/ 14 августа 2009

Учитывая, что выборки в IE - это боль, особенно когда дело доходит до всей проблемы с наслоениями, когда выбор появляется над элементом div, даже если это не так, могу я указать вам направление управления кнопками меню YUI. Они выглядят очень красиво, просты в реализации и не вызовут этой проблемы

Вот ссылка: http://developer.yahoo.com/yui/examples/button/btn_example07.html

0 голосов
/ 13 августа 2009

Многие люди, публикующие решения / примеры, похоже, не осознают одну вещь: событие onmouseout на <div> срабатывает перед событием onmouseover на <select>.

Когда <div> теряет фокус (onmouseout), не закрывайте его сразу, а, скажем, через 500 миллисекунд. Если в течение этого времени <select> получает фокус (наведение мыши), не закрывайте <div> вообще (clearTimeout).

Также попробуйте поиграть с распространением / всплытием событий.

0 голосов
/ 13 августа 2009

Почему при наведении мыши на <div>? Почему бы просто не показать <div> при наведении мыши, затем установить <body onmouseover="hidedivs();"> Я не знаю, сработает ли это, но если <div> находится сверху тела, тогда <div> должно оставаться видимым.

0 голосов
/ 13 августа 2009

Что-то вроде этого:

        <div id="trigger">
            Hover over me!
        </div>

    <div class="container">
        <select>
            <option>Blah</option>
            <option>Blah</option>
        </select>
    </div>


$("#trigger").mouseover(function(){
    $('.container).show();
});

$(".container").mouseleave(function(){
    $(this).hide();
});

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

0 голосов
/ 13 августа 2009

Вы пробовали hover вместо эффектов наведения мыши / выхода?

$(".myDiv").hover(function(){
    $(this).show();
}, function {
    $(this).hide();
});
0 голосов
/ 13 августа 2009

Ну, причина такого поведения в том, что всплывающие сообщения о событиях mouseover / out, что фактически означает, что всякий раз, когда вы наводите курсор мыши на любой из элементов внутри всплывающего окна, всплывающее окно также получает событие.

Вы можете прочитать больше здесь об этих событиях и здесь о пузырях событий.

У вас есть 3 возможных решения здесь:

  1. Измените события на onmouseenter / отпуска. Вы упомянули, что это не помогло, что звучит довольно странно, поскольку они не должны пузыриться.

  2. Проверьте srcElement относительно from / toElement в событии.

Улучшенная версия проверки McKAMEY будет выглядеть так:

function isReal() {
  var evt = window.event;
  if (!evt) {
      return true;
  }

  var el;
  if (evt.type === "mouseout") {
      el = evt.toElement;
  } else if (evt.type === "mouseover") {
      el = evt.fromElement;
  }
  if (!el) {
      return false;
  }
  // this will also return true if el == evt.srcElement
  return evt.srcElement.contains(el);
}

делает то же самое, только короче.

3. Другой вариант - создать прозрачный, невидимый div прямо под вашим всплывающим окном, которое покрывает область, в которую попадает поле выбора. Я предполагаю, что он выпадает за пределы реальной области всплывающего окна.

Надеюсь, это поможет!

0 голосов
/ 13 августа 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...