【问题标题】:HTML input that takes only numbers and the + symbol仅接受数字和 + 符号的 HTML 输入
【发布时间】:2016-09-20 07:33:19
【问题描述】:

我正在尝试为只接受数字和加号 (+) 的电话号码构建自定义文本输入;所有其他字符都需要被丢弃,并且不会显示在该字段上。

我正在尝试使用事件处理程序(onkeydown/onkeypress)并丢弃与其他键对应的输入。但是,我想不出一种跨浏览器的方法来做到这一点。以下是我尝试过但不起作用的方法:

  • 使用 onkeypress 事件并查看 event.key 来确定按下了哪个键:在 Chrome 上不起作用(请参阅 http://caniuse.com/keyboardevent-key)。有没有跨浏览器的解决方法?

  • 使用 onkeycode 事件并查看 event.keyCode: 当我们需要按多个键来打印一个字符时(例如,英文键盘布局需要按 Shift 和= 给 +)。此外,它还允许出现诸如 !@#$%^&*() 之类的字符,因为这些字符在按下 Shift 和数字时出现。 (这是JavaScript keycode allow number and plus symbol only 中采用的方法,但对我没有多大帮助;))

  • 使用 HTML 模式属性:这似乎并没有真正阻止人们写出他们喜欢的任何东西。

谢谢!

【问题讨论】:

  • 您可以使用 onkeyup 事件,获取整个输入并使用正则表达式过滤掉任何不需要的字符
  • @evolutionxbox 不,它不是重复的。该链接中遵循的方法正是我尝试过但不起作用的方法之一。第一篇文章第二个要点解释了它不起作用的原因。
  • 该方法可能行不通,但问题本质上是一样的。这使它成为重复项。无论如何,@RobinvdA 建议的方法很可能是您想要的。
  • @RobinvdA 如果您正在对输入值进行正则表达式并对其进行清理,则除非您知道保持光标位置的跨浏览器方式,否则光标将被强制到文本框的末尾。我遇到了很多令人愤怒的界面,它们不必要地执行该操作并阻止我在文本中间修复某些内容。

标签: javascript html validation user-input


【解决方案1】:

还有另一种解决方案,您可以使用Array.prototype.filter() 删除坏字符,并使用Array.prototype.join() 重新创建字符串,然后再将其插入输入。

您可以使用oninput 事件。当用户在 <input> 字段中写入内容时,它会执行 JavaScript。


见下例

var inputEl = document.getElementById('tel');
var goodKey = '0123456789+ ';

var checkInputTel = function(e) {
  var key = (typeof e.which == "number") ? e.which : e.keyCode;
  var start = this.selectionStart,
    end = this.selectionEnd;

  var filtered = this.value.split('').filter(filterInput);
  this.value = filtered.join("");

  /* Prevents moving the pointer for a bad character */
  var move = (filterInput(String.fromCharCode(key)) || (key == 0 || key == 8)) ? 0 : 1;
  this.setSelectionRange(start - move, end - move);
}

var filterInput = function(val) {
  return (goodKey.indexOf(val) > -1);
}

inputEl.addEventListener('input', checkInputTel);
<input type='tel' id='tel' />

注意:我使用输入类型 tel 来显示智能手机或平板电脑中的默认数字键盘。

电话: 用于输入电话号码的控件;换行符会自动从输入值中删除,但不会强制执行其他语法。您可以使用 patternma​​xlength 等属性来限制在控件中输入的值。 :valid:invalid CSS 伪类将酌情应用。

参考:MDN <input>

【讨论】:

  • 基本上可以,但是有输入闪烁的问题。用 onkeypress 做同样的事情可能会更干净。
  • 这会破坏使用 ctrl-a 选择字段的值。
  • 除了change,你不妨听听input;它会在 Chrome(和 Firefox?)中更好地工作。
  • 在我的旧 chrome 中,它运行良好,除了它会在任何无效输入时跳到末尾。
  • 如果您尝试在输入末尾之外的某个位置键入内容,这会以一种不稳定的方式运行,因此我不会按原样使用它。当值改变时,它需要代码来恢复插入符号的位置。
【解决方案2】:

始终尝试进行服务器端验证,这是为了“帮助”用户,而不是验证数据,(您可以随时打开控制台并根据需要更改输入值的值)

现在,我会使用的方法是:

在更改时检查整个输入的值,并使该值通过正则表达式以清除不需要的字符,同时跟踪“文本光标”的位置

const tel = document.getElementById('tel');

tel.addEventListener('input', function() {
  let start = this.selectionStart;
  let end = this.selectionEnd;
  
  const current = this.value
  const corrected = current.replace(/([^+0-9]+)/gi, '');
  this.value = corrected;
  
  if (corrected.length < current.length) --end;
  this.setSelectionRange(start, end);
});
&lt;input type="tel" id="tel"&gt;

您可以根据自己的需要制作更“准确”的正则表达式,这是一个很好的工具:RegExr

【讨论】:

  • 为什么你的 phoneRegExp 中有一个前瞻?
  • “请注意,此正则表达式将允许任何具有至少一个数字的值” - 相关的正则表达式是您在 val.replace(...) 中使用的,它不保证至少有一个数字。
【解决方案3】:

我建议你看看这个项目。 https://github.com/igorescobar/jQuery-Mask-Plugin/

您可以按原样使用它: $('.phone').mask('0000-0000'); 示例:https://igorescobar.github.io/jQuery-Mask-Plugin/

或者你可以阅读源代码,看看他们是如何解决的。

【讨论】:

  • 他们的方法看起来很有趣,但他们在作弊。 ;-) 显然,面具并不关心你按下哪个键。如果您希望输入 (,您不妨按一个数字或 + 键;它总是会打印一个 (。这不是我想要的,但如果我们想不出其他任何东西,这是一个有趣的选择. 谢谢!
【解决方案4】:

这种强大的通用方法的灵感来自@R3tep 的回答。它允许通过类似于pattern attributedata-filter 属性定义正则表达式模式:

// Apply filter to all inputs with data-filter:
let inputs = document.querySelectorAll('input[data-filter]');

for (let input of inputs) {
  let state = {
    value: input.value,
    start: input.selectionStart,
    end: input.selectionEnd,
    pattern: RegExp('^' + input.dataset.filter + '$')
  };
  
  input.addEventListener('input', event => {
    if (state.pattern.test(input.value)) {
      state.value = input.value;
    } else {
      input.value = state.value;
      input.setSelectionRange(state.start, state.end);
    }
  });

  input.addEventListener('keydown', event => {
    state.start = input.selectionStart;
    state.end = input.selectionEnd;
  });
}
<input type='tel' data-filter='[0-9|+]*' placeholder='123+456'>
<input type='tel' data-filter='(\+|(\+[1-9])?[0-9]*)' placeholder='+10123'>
<input type='text' data-filter='([A-Z]?|[A-Z][a-z]*)' placeholder='Abcdefg'>
<input type='text' data-filter='([A-Z]{0,3}|[A-Z]{3}[0-9]*)' placeholder='ABC123'>

【讨论】:

  • 好方法,它具有完全通用的区别。
  • @R3tep,是的,我喜欢它。我会竖起大拇指并投赞成票,因为它是隐式路线的试探性。但糟糕的是,它仅适用于最新的浏览器。在这种情况下,我想我宁愿使用 ,如果他们想使用我的网络应用程序,请让我的客户切换到 Safari 并升级到版本 8。这样更容易,也更干净。
【解决方案5】:

使用输入

type="tel" 或 "phone"

它在手机中显示默认数字键盘。

希望这会有所帮助:)

【讨论】:

  • 这不是跨浏览器解决方案。
  • @Kevin 为不清楚而道歉。虽然 OP 正在寻求限制输入的某些字符。 bhagya 提供了在手机中显示数字键盘的答案,而这在桌面浏览器中不会出现,因此允许输入任何字符。这并不能直接回答 OP 的问题。
【解决方案6】:

结合使用 keyup 事件侦听器、一些 RegEx/String 比较方法和一个中间变量,我能够得出以下结论:

var ele = document.getElementById('phone');
var curr = "";
var regexPatt = /^(0|[1-9][0-9]*)$/;
ele.addEventListener('keyup',function(e){
  var code = e.keyCode || e.which;
  if(this.value.match(regexPatt) || this.value.indexOf('+') > -1 || code == 8){
    curr = this.value;
    this.value = curr;
  } else {
    this.value = curr;
  }
});

看看小提琴:https://jsfiddle.net/Lg31pomp/2/

这似乎适用于数字、+ 字符以及用户退格输入元素时。

【讨论】:

  • 不阻止在空格后添加无效字符,阻止用户使用箭头键导航光标或使用 [ctrl]+[a] 进行选择。
【解决方案7】:

您的输入应如下所示:

<input type="text" onkeypress='return isNumberKey(event);'>

这是脚本:

function isNumberKey(evt) {
    var charCode = (evt.which) ? evt.which : event.keyCode;
    console.log(charCode);
    if (charCode != 43 &&  charCode > 31
        && (charCode < 48 || charCode > 57))
        return false;

    return true;
}

这是众多可能的解决方案之一。

【讨论】:

  • 这在我们需要按多个键来打印一个字符时不起作用(例如,英文键盘布局需要按 Shift 和 = 来给出 +)。
  • @BekinBacaj,我已经测试了这个解决方案,并确定 onkeydown 事件在我们需要按住键输入字符时没有帮助。如果我们使用 onkeypress 代替它会很有用,但这在 Chrome 上不起作用。考虑到这一点,以及这一点已经在开场问题中得到解释,我相信我的反对票是有道理的。
  • @unpollito,-他正在使用 onkeypress 事件。您使用 onkeydown intead 是错误的。我的 sn-p 正在使用 onkeypress,它不介意您使用 ( shift & = ) 符号或 ( alt & 4 & 3 ) 来写加号 (+) 。它只允许输入允许的符号所需的任何组合键。糟糕的是,他的代码一开始就不是他自己的——因此是错误的,即根本不起作用——这就是保证你投票的“原因”。
  • 很公平,你是对的 - 我看错了。我已经测试了你的方法并且它有效。对不起,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-18
  • 2012-09-29
  • 2022-01-09
  • 2010-12-17
  • 2017-08-08
  • 1970-01-01
相关资源
最近更新 更多