最近研究了一哈怎样实现用户边输入边添加yy-MM-dd hh:mm:ss格式功能,虽然实现了功能,但是总感觉用的是笨办法,大家有什么更好的方法希望可以指教哈我,谢谢。
我用的是卡位数的方法来实现功能的,既是每次检验用户光标即输入的位置,然后根据位置不同,按需求拼接字符串,然后替换input中原来的字符串,然后在将光标位置移动到对应的位置。所以我觉得这是一个笨办法,但是又实在不知道大神们是怎么实现的。
因此,我们需要知道移动input中光标的方法:
//移动光标到指定的pos处,obj为input元素的jq对象
var changeCursorPos= function(obj, pos) {
var inpObj = obj[0];
if (inpObj.setSelectionRange) {
inpObj.setSelectionRange(pos, pos);
} else {
console.log('不兼容该方法');
}
}
以及根据光标得到当前输入的是第几位:
//根据光标得到当前输入的是第几位
var getIndex= function(obj){
var oTxt1 = obj[0];
var cursurPosition=-1;
if(oTxt1.selectionStart){//非IE浏览器
cursurPosition= oTxt1.selectionStart;
}else{//IE
var range = document.selection.createRange();
range.moveStart("character",-oTxt1.value.length);
cursurPosition=range.text.length;
}
return cursurPosition-1;
}
然后,我们要求只能按数字键,避免其他按键的干扰,因此在keydown时检验,数字键的keyCode是96到105以及48到57,以一个flag变量来标志按下的是否是某一个数字键,如下:
$tempInput.bind('keydown',function(event){
var keyCode=event.keyCode;
console.log(keyCode);
for(var i=96;i<=105;i++){
if(keyCode==i){
flag=1;
break;
}
}
if(flag==0){
for(var i=48;i<=57;i++){
if(keyCode==i){
flag=1;
break;
}
}
}
然后还需要限制只能够输入19位
//valueLength位限制输入的位数
if(flag==1) {
var index = getIndex($(':focus'));
if (index >= valueLength) {
return false;
}
if ($(this).hasClass('running')) {
return false;
}
$(this).addClass('running');
}else{
return false;
}
分析我们所要实现的yy-MM-dd hh:mm:ss格式,以输入月份为例,有两种情况,分别是以下两种位置;
当光标位于如图一所在位置时,因为月份不能大于12,因此,我们需要检验此时输入的数是否小于等于1并且第三位即月份的个位数是否小于2,如是,则只需要拼接好'-'字符并且输入的数替换下一位。比如此时input的value为:2012-01-23 21:21:21时。如果不是,则我们需要拼接好'-'字符,并且输入的数要替换第三位即月份的个位数,比如此时value为:2012-09-23 21:21:21。还有一种情况是当此时输入的数等于十位所允许最大数,第三位小于十位为最大数个位所允许的最大数时,还是直接替换下一位并拼接好‘-’字符,比如此时value值为2012-01-23 21:21:21,此时想输入3。
//当前光标所在位置即输入位置 当前input的value值 连接符号 所允许的十位数的最大数 所允许的个位数的最大数 当十位最大时所允许的个位最大数
var specificSymbol= function(index,string,sym,num,breakPoint,another){
var i=index,str=string,symbol=sym,number=num,breakPoint=breakPoint,another=another;
var val=str[i]; //当前输入的数
var result={};
var thirdNumber=str.substr(i+3,1);//需要检验的第三个数
if(val
当光标位于如图二所在位置时,与上面一样的情况,只是他不需要拼接特殊符号比如:‘-’,因此代码如下:
//当前光标所在位置即输入位置 当前input的value值 所允许的十位数的最大数 所允许的个位数的最大数 当十位最大时所允许的个位最大数
var specific= function(index,string,num,breakPoint,another){
var i=index,str=string,number=num,breakPoint=breakPoint,another=another;
var val=str[i]; //当前输入的数
var thirdNumber=str.substr(i+2,1);//需要检验的第二个数
var result={};
if(val<=number&&thirdNumber<=breakPoint){
str=str.substring(0,i)+val+str.substring(i+2,str.length);
result.index=i+1;
result.string=str;
}else if(val==number&&thirdNumber<=another){
str=str.substring(0,i)+val+str.substring(i+2,str.length);
result.index=i+1;
result.string=str;
}
else{
str=str.substring(0,i)+'0'+val+str.substring(i+3,str.length);
result.index=i+2;
result.string=str;
}
return result;
}
当光标位于图三位置时,还是拿月份当例子,如果输入位前面一位满足了小于等于1,然后此时输入9,显然是不行的,所以需要在这里进行限制,当当前位数的前一位数大于等于十位数的最大数并且输入的数大于了个位允许的最大数,则将十位数变为0,然后当前输入的数替换个位数,比如此时input的value是2012-10-12 21:21:21。否则的话就直接替换下一位数,其它的不变。
//当前光标所在位置即输入位置 当前input的value值 所允许的十位数的最大数 当十位数为最大时所允许的个位数的最大数
var specificNum=function(index,string,num,breakPoint){
var i=index,str=string,number=num,breakPoint=breakPoint;
var val=str[i]; //当前输入的数
var result={};
var frontNumber=str.substr(i-1,1);
console.log(frontNumber);
if(frontNumber>=number&&val>breakPoint){
console.log(str.substring(i+2,str.length));
str=str.substring(0,i-1)+'0'+val+str.substring(i+2,str.length);
result.index=i+1;
result.string=str;
}else{
str=str.substring(0,i+1)+str.substring(i+2,str.length);
result.index=i+1;
result.string=str;
}
return result;
}
仔细分析了可以发现,当输入的是天,小时,分钟,秒时也是需要符合上面两种情况的,只是连接符号及十位及个位所允许的最大位数不同,比如天的话,最大允许的十位数是3,最大允许的个位数是9(抱歉,我实在不想判断润年和非闰年以及大小月,因此输入日期的时候默认是可以输入31号的,有兴趣的可以自己在加一下限制),年份的话只需要直接替换下一位,因此调用时代码就只需要调用上面的两个方法:
$tempInput.bind('input propertychange',function(event){
if(flag==1){
var val=$(this).val();
var index=getIndex($(':focus'));
console.log(index);
if(index==4){
var result=specificSymbol(index,val,'-',1,9,2);
}else if(index==5){
var result=specific(index,val,1,9,2);
}else if(index==6){
var result=specificNum(index,val,1,2);
}else if(index==7){
var result=specificSymbol(index,val,'-',3,9,1);
}else if(index==8){
var result=specific(index,val,3,9,1);
}else if(index==9){
var result=specificNum(index,val,3,1);
}else if(index==10){
var result=specificSymbol(index,val,' ',2,9,4);
}else if(index==11){
var result=specific(index,val,2,9,4);
}else if(index==12){
var result=specificNum(index,val,2,4);
}else if(index==13||index==16){
var result=specificSymbol(index,val,':',5,9,9);
}else if(index==14||index==17){
var result=specific(index,val,5,9,9);
}
else{
var result={};
result.string=val.substring(0,index+1)+val.substring(index+2,val.length);
result.index=index+1;
}
$(':focus').val(result.string);
changeCursorPos($(':focus'), result.index);
$(this).removeClass('running');
flag=0;
}
});
最后附上完整代码:
Title
最后说一句,我最开始用的keyup事件,这就导致输入时,总是会闪烁,因为keyup触发时,数字已经被输入到input中了,然后又各种苦恼,最后发现用input及IE的propertychange事件可以避免闪烁,因为这个事件时input值发生变化是触发,值变化时改变value的值就不会闪烁啦!
忽略我的各种取名吧~(笑哭),我也觉得这种卡位数是很笨的办法,有大神有更好的办法的话,求指教!