卡号正则表达式和 caret/cursor 位置 (javascript)

Card Number Regex and caret/cursor position (javascript)

我有一个正则表达式可以将信用卡号分成 4 组,每组 4 位数字。

Regex 工作正常,但如果我想返回到字符串并对其进行编辑,光标会跳转到选择的末尾。

<input id= "cardNumber" maxlength="19" type="tel"/>

JS如下:

document.getElementById('cardNumber').addEventListener('input', function (e) {

var field = e.target;

field.value = field.value.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, ' ').trim();

});

显然我不希望光标跳到条目的末尾。我一直在玩弄插入符号位置、selectionStart 和 End,但到目前为止运气不好。

非常感谢任何指点。

在此处查看 jsfiddle:https://jsfiddle.net/oo7Ljm4j/1/

您可以使用 keyup 来检查返回键是否是一次按下什么都不做

document.getElementById('cardNumber').addEventListener('keyup', function (e) {
  var key = event.which || event.keyCode || event.charCode;
  var field = e.target;
  if (key !== 8) {
    field.value = field.value.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, ' ').trim();
  }
});

DEMO


您可以创建一个函数,在文本输入的每个键事件中使用它来完全禁用非整数字符并防止粘贴非整数字符

document.getElementById('cardNumber').addEventListener('keyup', format);
document.getElementById('cardNumber').addEventListener('keydown', format);
document.getElementById('cardNumber').addEventListener('copy', format);       
document.getElementById('cardNumber').addEventListener('keypress', format);

function format(e) {
    var key = event.which || event.keyCode || event.charCode;
    var field = e.target;
    if (key !== 8) {
      field.value = field.value.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, ' ').trim();
    }
}

DEMO

如果添加此条件,您也可以接受箭头

(key < 37 || key > 39)

所以你的状态会是这样

if (key !== 8 && (key < 37 || key > 39)) {
    field.value = field.value.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, ' ').trim();
}

DEMO

好的,经过一番挖掘,我找到了答案!

通过使用 field.selectionEnd 并在每次(打开)输入时重置它,它会将光标保持在您想要编辑的位置。

问题源于以下事实:当您对其进行更改时,正则表达式将重新呈现并更新整个字段(因此,显然,当正则表达式触发时,光标默认为值的末尾浏览器每次都认为你完成了。)

  document.getElementById('cardNumber').addEventListener('input', function (e) {

  var field = e.target, position = field.selectionEnd, length = field.value.length;


  field.value = field.value.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, ' ').trim();


  field.selectionEnd = position += ((field.value.charAt(position - 1) === ' ' && field.value.charAt(length - 1) === ' ') ? 1 : 0);    
});

这样我们告诉光标重新计算它在每个输入上的 selectionEnd 位置。

查看正在运行的 JSFiddle aqui:https://jsfiddle.net/oo7Ljm4j/6/