Javascript onChange клавиши со стрелками - PullRequest
8 голосов
/ 05 июля 2011

Хорошо, мы все знаем, что onChange используется для выполнения кода javascript в операторе select при изменении опции. Однако если вы измените оператор выбора с помощью клавиш со стрелками, событие onChange не вызывается. Это можно обойти? Пожалуйста помоги! Я ОКР, я знаю.

- РЕДАКТИРОВАТЬ 1 -

Только что проверил это в IE и клавиши со стрелками работают. Видимо это просто Chrome. ** собирается проверить Firefox

- Правка 2 -

Протестировано в Firefox и реализовано незадолго до того, как в приведенном ниже ответе говорилось о том, что для изменения требуется действие onBlur. Итак, ответ здесь:

Internet Explorer распознает события onChange с клавиатуры, а также нажимает на них. Firefox и Chrome требуют, чтобы за ключевыми событиями следовало размытие, чтобы вызвать onChange.

Теперь, как правило, мне не нравится Internet Explorer, потому что это кусок мусора ... Но я думаю, что ... к сожалению, должен сказать, что они правильно поняли.

Мое понимание причин размытия в chrome и firefox заключается в экономии ресурсов, но я с этим не согласен. Я чувствую, что это должно следовать буквальному толкованию команды onChange ... Вздох ... Я полагаю, что, возможно, я как-то ошибаюсь.

Ответы [ 6 ]

4 голосов
/ 19 июня 2013

Возвращаясь к этому, похоже, что после постановки этого вопроса Chrome теперь запускает onChange после ключевых событий. Firefox, кажется, все еще ждет onblur. http://jsfiddle.net/2aQBN/

$(document).ready(function() {
    $("#test").on("change", function() {
        console.log("Changed.");
    });
});

Спецификация W3C предлагает использовать вместо него событие input.

Когда применяется событие ввода, каждый раз, когда пользователь вызывает элемент Чтобы изменить значение, пользовательский агент должен поставить задачу в очередь, чтобы запустить простой событие, которое всплывает с именем input на элементе input.

Однако в элементах Chrome или Firefox для элемента select не отображается событие ввода. (Просто введите элементы.)

Тест, демонстрирующий текущее значение по сравнению с последним значением onchange.

http://jsfiddle.net/teynon/MpyHK/5/

Firefox изменит значение onmouseover. Изменение ключа также изменит значение. Тем не менее, onchange не выстрелил. Если форма отправляется в то время, когда у пользователя открыто меню выбора, отправляется выделенная в данный момент опция.

Из W3C:

Если атрибут Multiple отсутствует и элемент не отключен, тогда пользовательский агент должен позволить пользователю выбрать элемент опции в его список опций, который сам по себе не отключен. По этой опции выбранный элемент (либо с помощью щелчка, либо с помощью расфокусировки элемент после изменения его значения , либо с помощью команды меню, либо через любой другой механизм), и до соответствующего взаимодействия с пользователем событие ставится в очередь (например, до события click), пользовательский агент должен установить отобранность выбранного элемента option в true, а затем поставить в очередь задача, чтобы запустить простое событие, которое по имени пузырьки меняются на выбор элемент, используя источник задачи взаимодействия с пользователем в качестве источника задачи.

На https://bugzilla.mozilla.org/show_bug.cgi?id=126379 идет долгое обсуждение этого вопроса, и многие люди просят, чтобы работали клавиши со стрелками. (И некоторые защищают подход onchange.)

Некоторые пользователи предположили, что W3C неверно описан в спецификации для события select элемента change. Вместо этого мы предлагаем внести изменения в спецификацию того, как мы ожидаем, что функциональность select onchange будет работать.

Текущая функциональность явно не интуитивна для большого числа людей, основываясь исключительно на количестве сообщений об ошибках. (У Mozilla 40 помечены как дубликаты.)

4 голосов
/ 05 июля 2011

Прокрутка в окне выбора не считается изменением. Изменение происходит, когда вы размываете () элемент select, и новое значение параметра применяется к элементу select.

4 голосов
/ 05 июля 2011

Я бы предложил вам написать необходимый код в событии Key Up, чтобы зафиксировать нажатие клавиши, а также проверить код клавиши. Надеюсь, это поможет

2 голосов
/ 19 ноября 2013

Это довольно грязный хак, но вы можете принудительно вызвать событие change, выполнив следующее:

element.addEventListener('keyup', function(evt){
    evt.target.blur();
    evt.target.focus();
}, false);

Таким образом, вы также зарегистрируете прослушиватель событий для change,и эта функция вызывается, когда пользователь нажимает клавишу на <select> с помощью приведенного выше кода.

Возможно, вы захотите охватить это только Firefox, но AFAIK вам придется использовать UA sniffing для этоготак что решать вам, если это приемлемо.

Источник

0 голосов
/ 20 апреля 2018

Вот реализация этого запроса. Для краткости только показ кода. См. https://github.com/ida/skriptz/blob/master/js/fields/select/selection_changed.js для подробных объяснений в комментариях.

function addSelectionChangedListener(selectionEle, onChangeDoWithEle) {

  var selectedIndex = null

  function onChangeEvent(eve) {
    // If selection-change was caused of an option's click-event:
    if(eve.explicitOriginalTarget.tagName.toLowerCase() == 'option') {
      // We want to trigger passed event-handler:
      onChangeDoWithEle(eve.target)
    }
  }

  function onKeyEvent(eve) {

    // Key-event is keydown, remember current selectedIndex:
    if(eve.type == 'keydown') {
      selectedIndex = eve.target.selectedIndex
    }
    // Key-event is keyup, if selection changed, trigger passed handler:
    else if(selectedIndex != eve.target.selectedIndex) {
      onChangeDoWithEle(eve.target)
    }

  }

  selectionEle.onchange  = function(eve) onChangeEvent(eve)
  selectionEle.onkeydown = function(eve) onKeyEvent(eve)
  selectionEle.onkeyup   = function(eve) onKeyEvent(eve)

}
0 голосов
/ 10 августа 2015

Я думаю о чем-то вроде этого (чтобы не вызывать событие, если значение не было изменено):

            select.keydown(function(){
                var _this = $(this);
                var _val = $(this).val();

                setTimeout(function(){    
                    if(_this.val() !== _val){
                        _this.trigger("change");
                    }
                }, 1);
            });
...