Прослушиватели событий (onkeypress, onkeydown) на входе не работают в цифровой клавиатуре Android

У меня есть простой вход

<input type="number">

Я хочу, чтобы это признать только цифры (цифра [0-9]) и ничего более. Для этого я добавил прослушиватель событий, где я контролирую код ключа события.

ничего особенного и все работает практически на всех платформах, проблемы с Android. Здесь

type= "number"

вызывает появление цифровой клавиатуры - и это здорово - с некоторыми другими символами (запятая, точка, дефис...). При нажатии одного из этих специальных символов поведение странно:

  • метода onkeypress событие: абсолютно не стреляли (почему???)
  • OnKeyDown событие: событие срабатывает и вызывается относительная функция. Проблема в том, что браузер уже введен символ (почему??) поэтому невозможно вызвать функцию "preventDefault" из "event".
  • on input event: событие запускается, но" код "и" какие "свойства объекта" event " не определены. Более того, как и раньше, браузер уже введен символ.

что я упустил?

моя среда powerd от AngularJs, поэтому я настроил прослушиватели событий внутри директивы. Однако делать то же самое с jQuery не решает проблемы.

кто-то может предложить использовать "$parsers", чтобы подтолкнуть мое пользовательское значение без нежелательных символов. В любом случае это не работает, я думаю, потому что тип ввода - "номер", и он ожидает только номера (еще один способ сказать, что браузер на Android делает что-то не так..)

здесь рабочая скрипку, откройте его на Android.

спасибо

3 ответов


насчет этой директивы $parsers.unshift:

app.directive('format', ['$filter', '$window', function($filter, $window) {
  return {
    require: '?ngModel',
    link: function(scope, elem, attrs, ctrl) {

      if (!ctrl) return;

      scope.plainNumber = scope.test+'';

      ctrl.$parsers.unshift(function(viewValue) {         

      if(!viewValue){
         viewValue = scope.plainNumber;
      }
        scope.plainNumber = viewValue.replace(/[^\d]/g, '');

        elem.val(scope.plainNumber);
        return scope.plainNumber;            
      });
    }
  };
}]); 

и использование:

<input type="number" ng-model="test" format /> 

Демо-Скрипка


протестировано на Android


на keypress событие не запускается, только keydown и keyup. onkeydown вы можете вызвать preventDefault() метод. Но что мешает? charCode всегда 0 и keyCode и 229. Вы должны проверить все входные данные.

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

if(!event.charCode) {
    this.removeInvalidChar();
    return;
}

private removeInvalidChar(): void {
    setTimeout(() => {
        let input = this.control.control.value;

        if (input) {
            input.split('').forEach((char: string) => {
                if (!this.pattern.test(char)) {
                    input = input.replace(char, '');
                }
            });
            this.control.control.setValue(input);
        }
    });
}

используйте inputType= "numberSigned" он предоставит вам только номера между 0-9 , по крайней мере, в родном android он работает безупречно.