Javascript 如何跟踪输入字段中的字符位置、删除、插入和替换?

Javascript 如何跟踪输入字段中的字符位置、删除、插入和替换?,javascript,html,Javascript,Html,我正在创建一个日期格式化程序 在输入(输入事件)时,它将根据用户类型将输入格式化为正确的格式,例如,2020年11月22日 必须满足某些条件 第一个字符(月份第一个字符必须为0或1) 如果月份中的第一个字符是1,则第二个月份字符必须是0、1或2 分隔符(“/”)将作为用户类型自动插入 一天的第一个字符必须是0、1、2或3 除分隔符外的所有字符都必须是数字字符 当用户删除一个角色时,这个问题就会出现 如何在输入时跟踪字符的位置?另外,如何跟踪删除或替换的字符的位置?您可以尝试使用inputEl

我正在创建一个日期格式化程序

在输入(输入事件)时,它将根据用户类型将输入格式化为正确的格式,例如,2020年11月22日

必须满足某些条件

  • 第一个字符(月份第一个字符必须为0或1)
  • 如果月份中的第一个字符是1,则第二个月份字符必须是0、1或2
  • 分隔符(“/”)将作为用户类型自动插入
  • 一天的第一个字符必须是0、1、2或3
  • 除分隔符外的所有字符都必须是数字字符
当用户删除一个角色时,这个问题就会出现


如何在输入时跟踪字符的位置?另外,如何跟踪删除或替换的字符的位置?

您可以尝试使用
inputElement.value
获取值,然后检查值的长度是否超过2,然后添加/。 像这样的

var x = inputElement.value;
x = x + '/';
并在少于两个时将其移除 同样,您也可以检查月份的第一个数字是否为0、1或2,如果不是,则可以强制更改该数字

if (charCode == 8 || (charCode > 47 && charCode < 58))
if(charCode==8 | |(charCode>47&&charCode<58))
此检查将确保输入值仅为数字
这就是我所能帮助的。我想你可以自己解决剩下的问题,用try-and-catch来处理错误,我已经在JSFiddle()中做了一些测试

功能检查日期(val){
让pat=/^(0[1-9]|1[012])[/](0[1-9]|[12][0-9]|3[01])[/](19[124; 20)\d\d$/
如果(专利测试(val)){
document.getElementById('evals').innerHTML=“您好?”
}
否则{
document.getElementById('evals').innerHTML=“再见!”
}
}

我知道有办法做到这一点,但我似乎无法完全做到。在我的提琴中,只有当整个东西的格式正确时,它才会显示出来,而不是当用户输入时

一种方法是,将正则表达式放入数组,然后根据该点的正则表达式检查它放入的每个字符。如果它没有放入角色


如前所述,尝试使用
type=“date”
。我知道它没有那么酷,但它会工作得更好。。。这将告诉您最近按键的字符位置。你可以把它作为进一步计算的基础

inputElement.addEventListener("input", e => {
    console.log(e.target.selectionStart)
}

我添加了工作示例

regex
可用于验证日期格式(MM/DD/YYYY)。正则表达式是
^(1[0-2]|0[1-9])/(3[01]|[12][0-9]|0[1-9])/[0-9]{4}$

要获取光标位置,可以使用
e.target.selectionStart

const allowedSlashIndices=[2,5];
让prevValue='';
让currentValue='';
函数onChange(e){
常量文本=e.target.value;
regex=newregexp(“^(1[0-2]|0[1-9])/(3[01]|[12][0-9]|0[1-9])/[0-9]{4}$”;
如果(!正则表达式测试(文本)){
document.getElementById('error')。innerHTML='Invalid date';
}否则{
document.getElementById('error')。innerHTML='';
}
}
输入函数(e){
prevValue=当前值;
currentValue=e.target.value;
const nextIndex=e.target.value.length;
if(allowedSlashIndices.includes(nextIndex)&&prevValue!==currentValue){
e、 target.value=`${e.target.value}/`;
}
}
函数onKeydown(e){
如果(IsNumber或斜杠(e)){
if(i(e)){
const cursorIndex=e.target.selectionStart;
如果(!allowedSlashIndices.includes(cursorIndex)){
e、 预防默认值();
}
}
}否则{
//不允许使用数字以外的键
e、 预防默认值();
}
}
函数IsNumberScrash(evt){
evt=evt?evt:window.event;
const charCode=evt.which?evt.which:evt.keyCode;
常量isNotNumber=charCode>31&(charCode<48 | | charCode>57);
常量箭头键=[37,38,39,40]。包括(字符码);
常量isNotSlash=charCode!==191;
如果(isNotNumber&&isNotSlash&&!箭头键){
返回false;
}
返回true;
}
函数IsFlash(evt){
evt=evt?evt:window.event;
const charCode=evt.which?evt.which:evt.keyCode;
返回charCode==191;
}

//变量t有用户输入,其长度是光标位置
//代码开始
var t=“”
var x=document.getElementById('asdf')
x、 onkeydown=功能(ev){
ev.preventDefault()
如果(ev.key.length==1){t+=ev.key}
else if(ev.key==“退格”){
t=t.split``.filter((a,i)=>{return i!=t.length-1})。连接``
}
x、 值=t;setCaretText(x.id,t.length)
log(getCaretIndex(x))//如果您不想控制用户光标的位置,但仍要获取光标位置
}
//代码端
//随机辅助函数
函数setCaretDom(ell,n){//为非输入标记设置
var el=document.getElementById(el);
var range=document.createRange();
var sel=window.getSelection();
range.setStart(el.childNodes[0],n)
范围。塌陷(真);
选择removeAllRanges();
选择添加范围(范围);
el.focus();
}
函数setCaretText(elemId,caretPos){//为输入标记设置
var elem=document.getElementById(elemId);
if(elem!=null){
if(元素createTextRange){
var range=elem.createTextRange();
range.move('character',caretPos);
range.select();
}
否则{
元素焦点();
元素设置选择范围(caretPos,caretPos);
}
}
}
函数getCaretIndex(inputField){//为输入标记设置
const startPos=inputField.selectionStart;
const endPos=inputField.selectionEnd;
const dir=inputField.selectionDirection;
如果(起始位置===结束位置){
返回startPos;
}
if(dir==“forward”){
返回端POS;
}否则{
返回startPos;
}
}

好的,我只做了多一点