Выбор HTML с отключенным параметром возвращает неверный selectedIndex в FireFox - PullRequest
7 голосов
/ 03 августа 2011

У меня есть Select с отключенным Option, который выбран по умолчанию:

<select name="select" size="1">
   <option>0</option>
   <option selected disabled>1</option>
   <option>2</option>
   <option>3</option>
   <option>4</option>
</select>

Если я получаю выбранное, возвращается 1. Все в порядке.

Но если я открою всплывающее окно и наведите курсор на другой курсор Option (например, '4')
и отмените его с помощью ESC или щелкните в любом месте остальное.

Вход Select показывает старое значение 1, но возвращается при выборе 4.

Пример с jsfiddle

Этого не происходит только с Chrome FireFox (4/5)

Ответы [ 4 ]

1 голос
/ 17 августа 2011

Обнаружение ключа esc и его сброс, вот пример использования jQuery (и тире вашего кода)

$('select').keyup(function(e) {
  if (e.keyCode == 27) {
  document.getElementsByName('select')[0].selectedIndex = 1;
  }
});

ОБНОВЛЕНИЕ Нет решения jQuery

ОБНОВЛЕНИЕ 2 Абстрагированный поиск события и код ключа для повторного использования.

DEMO: http://wecodesign.com/demos/stackoverflow-6923135.htm

<script type="text/javascript">
function getEvent( event ) {
    if ( window.event ) return window.event;
    return event;
}
function getKeycode ( event ) {
    if ( event.which ) return event.which;
    else return event.keyCode;
}
changeToDefaultListener = function( event ) {
    theEvent = getEvent( event );
    theKeyCode = getKeycode( theEvent );
    if( theKeyCode == 27 ) {
        document.getElementsByName( 'select' )[0].selectedIndex = 1;
    }
};
</script>
<select name="select" size="1">
   <option>0</option>
   <option selected disabled>1</option>
   <option>2</option>
   <option>3</option>
   <option>4</option>
</select>

<a href="javaScript:alert(document.getElementsByName('select')[0].selectedIndex);">getSelected</a>

<script type="text/javascript">
document.getElementsByName('select')[0].onkeyup=changeToDefaultListener;
</script>
1 голос
/ 18 августа 2011

Следующий код безобразен, но он делает именно то, что вы хотите (я думаю).По сути, я перехватываю все события onChange и обрабатываю их, только если есть соответствующее событие onClick, которое приводит к изменению значения.Также обратите внимание, что события изменения обрабатываются до событий щелчка.РЕДАКТИРОВАТЬ: Только что связал это не работает в Chrome, поэтому я добавил некоторый код обнаружения браузера, чтобы он выполнялся только в Firefox.

ПРИМЕЧАНИЕ. Текущий код не будет работать, если пользователь вставил вкладку в поле выбора ивнес свои изменения с помощью клавиш ошибок, но метод, описанный ниже, можно легко адаптировать и для этого случая.Вам просто нужно обрабатывать ключевые события, такие как стрелка вверх или стрелка вниз или TAB или ENTER, точно так же, как щелчки обрабатываются ниже, но только тогда, когда поле выбора было в фокусе.

ПРИМЕЧАНИЕ 2. Игра с этим больше, поведение очень странное.Если вы выходите из выбора, событие onChange не запускается, а сохраняется.Если в какой-либо последующий момент вы нажмете в любом месте на экране, событие onChange будет инициировано для значения, на которое вы навели курсор, когда вы сбежали, даже если это значение было фактически изменено сразу после вашего побега.Так что это становится сложно.Я думаю, что вам, возможно, придется рассматривать 2 случая отдельно.Один случай для обработки кликов, а другой - для выхода из выхода (на что ответил Патрик).

Становится волосатым, и я не вижу элегантного способа закодировать это.Как насчет примечания для пользователя рядом с текстовым полем, в котором говорится: «Выбранный в данный момент параметр 1 больше недоступен».Тогда у вас может быть поле выбора только с доступными опциями.

<select name="select" size="1" onChange="handleChange()" onClick="handleClick()" >
  <option>0</option>
  <option selected disabled>1</option>
  <option>2</option>
  <option>3</option>
  <option>4</option>
</select>
<br />


<script>
var initialValue = document.getElementsByName('select')[0].selectedIndex;
var potentialChange;
var processClick;

function handleClick() {

    //ignore this code if not firefox
    if (navigator.userAgent.indexOf("Firefox") === -1)
        return;

    var curVal = document.getElementsByName('select')[0].selectedIndex;
    if (!processClick)
        return;
    // a value change click occured, now we actually process it.
    document.getElementsByName('select')[0].value = potentialChange;
}
function handleChange() {
    // save the potential change, which will be used if a real click was detected
    potentialChange = document.getElementsByName('select')[0].selectedIndex;
    processClick = (potentialChange !== initialValue);
    // undo the attempted change, in case of an escape or page click
    // but only on firefox
    if (navigator.userAgent.indexOf("Firefox")!=-1)
        document.getElementsByName('select')[0].value = initialValue;

    document.getElementsByName('select')[0].value = initialValue;
}
</script>

<a href="javaScript:alert(document.getElementsByName('select')[0].selectedIndex);">getSelected</a>
1 голос
/ 03 августа 2011

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

Событие onChange не было запущено до события onBlur (когда происходит изменение selectedValue, но это не то, на что изменяется отображение). Если бы мы сбросили наше значение в событии onChange, это событие могло бы быть вызвано снова. Таким образом, используя событие onBlur, мы можем предоставить следующий обходной путь:

onBlur="javascript:document.getElementsByName('select')[0].selectedIndex = document.getElementsByName('select')[0].selectedIndex;"

http://jsfiddle.net/aRMpt/22/

Я надеюсь, что здесь есть смысл.

0 голосов
/ 24 июня 2013

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

var selectChanged = false;
$('#select option:not(:selected)').click(function () {
    selectChanged = true;
});

Затем в области кода, где мне нужно выбранное значение раскрывающегося списка, я проверяю логическое значение:

если логическое значение истинно, я могу использовать его новое значение

если логическое значение равно false, я могу получить значение из свойства Html (которое содержит начальное значение раскрывающегося списка).

var selectValue = selectChanged ? $('#select').val() : $($('#select').outerHtml()).find('option:selected').val()

Это ужасно, я знаю, но это единственная работа, которую я смог найти.

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