最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Event listeners (onkeypress, onkeydown) on input not working in Android numeric keyboard - Stack Overflow

programmeradmin1浏览0评论

I don't know why, but after hours spent dealing with this I can say there's something wrong.

I have a simple input

<input type="number">

I want it to accept only numbers (digit [0-9]) and nothing more. In order to achieve this I added an event listener where I control the keycode of the event.

Nothing special and everything working on almost all platforms, problems es with Android. Here the

type="number"

causes numeric keyboard to appear - and that's great - with also some other characters (ma, dot, hyphen...). When you press one of this special characters the behavior is strange:

  • onkeypress event: absolutely not firing (why???)
  • onkeydown event: the event is firing and the relative function is called. The problem is that the browser has already typed the character (why??) so is not possible to call the "preventDefault" function of "event".
  • on input event: the event is firing but "code" and "which" properties of "event" object are undefined. Moreover, like before, the browser has already typed the character.

What am I missing?

My environment is powerd by AngularJs so I setted up event listeners inside a directive. However doing same things with jQuery doesn't solve problems.

Someone can suggest to use a "$parsers" to push my custom value without unwanted characters. Anyway this doesn't work I guess because the type of the input is "number" and it expect only numbers (another way to say the browser on Android is doing something wrong..)

Here there's a working Fiddle, open it on Android.

I don't know why, but after hours spent dealing with this I can say there's something wrong.

I have a simple input

<input type="number">

I want it to accept only numbers (digit [0-9]) and nothing more. In order to achieve this I added an event listener where I control the keycode of the event.

Nothing special and everything working on almost all platforms, problems es with Android. Here the

type="number"

causes numeric keyboard to appear - and that's great - with also some other characters (ma, dot, hyphen...). When you press one of this special characters the behavior is strange:

  • onkeypress event: absolutely not firing (why???)
  • onkeydown event: the event is firing and the relative function is called. The problem is that the browser has already typed the character (why??) so is not possible to call the "preventDefault" function of "event".
  • on input event: the event is firing but "code" and "which" properties of "event" object are undefined. Moreover, like before, the browser has already typed the character.

What am I missing?

My environment is powerd by AngularJs so I setted up event listeners inside a directive. However doing same things with jQuery doesn't solve problems.

Someone can suggest to use a "$parsers" to push my custom value without unwanted characters. Anyway this doesn't work I guess because the type of the input is "number" and it expect only numbers (another way to say the browser on Android is doing something wrong..)

Here there's a working Fiddle, open it on Android.

Share edited Aug 11, 2019 at 8:32 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Feb 7, 2017 at 14:43 Ernesto SchiavoErnesto Schiavo 1,0602 gold badges14 silver badges36 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 7

The keypress event isn't fired, only keydown and keyup. onkeydown you're able to invoke the preventDefault() method. But what to prevent? charCode is always 0 and keyCode is 229. You should check all the input.

Something like this:

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);
        }
    });
}

What about this directive with $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;            
      });
    }
  };
}]); 

And usage:

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

Demo Fiddle


Tested on Android

use inputType="numberSigned" it will provide you only numbers between 0-9 , atleast in native android it works flawlessly.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>