由于项目上有需求要求输入银行卡号四位一空格的需求,改过好几版发现都有bug,最后优化了一版看起来效果还行,发帖留存。
难点是从中间插入和删除处理光标问题。
首先需要用到获取光标和设置光标的方法。
1 // 获取光标位置 2 function getCursortPosition(textDom) { 3 var cursorPos = 0; 4 if (document.selection) { 5 // IE Support 6 textDom.focus(); 7 var selectRange = document.selection.createRange(); 8 selectRange.moveStart('character', -textDom.value.length); 9 cursorPos = selectRange.text.length; 10 } else if (textDom.setSelectionRange) { 11 // webkit support 12 textDom.focus(); 13 cursorPos = textDom.selectionStart; 14 } 15 return cursorPos; 16 } 17 // 设置光标位置 18 function setCaretPosition(textDom, pos) { 19 if (textDom.setSelectionRange) { 20 textDom.focus(); 21 textDom.setSelectionRange(pos, pos); 22 } else if (textDom.createTextRange) { 23 // IE Support 24 var range = textDom.createTextRange(); 25 range.collapse(true); 26 range.moveEnd('character', pos); 27 range.moveStart('character', pos); 28 range.select(); 29 } 30 } 31 /** 32 * 账号输入时自动4位一空格 33 */ 34 $(function () { 35 var isDelete = false; 36 $("input[data-type='acc']").on("keyup", function (e) { 37 var elem = this; 38 //加timeout是为了处理安卓部分机型系统键盘无法录入的问题如vivo 39 setTimeout(function(){ 40 var str = elem.value; 41 var currentPos = getCursortPosition(elem); 42 var posAfterText = ""; 43 var posPreText = ""; 44 var isNextBlank = false;//后面的是否是空格 45 var isPreBlank = false; 46 var isLastPos = true; 47 if (currentPos != str.length) {//不是最后一个 48 posAfterText = str.substr(currentPos, 1); 49 posPreText = str.substr(currentPos - 1, 1); 50 isNextBlank = /^\s+$/.test(posAfterText); 51 isPreBlank = /^\s+$/.test(posPreText); 52 isLastPos = false; 53 } 54 if(elem.value.length <= $(elem).attr("maxlength")){//最大长度控制 55 elem.value = elem.value.replace(/\s/g, '').replace(/(\w{4})(?=\w)/g, "$1 "); 56 } 57 if (isDelete) { 58 if (isPreBlank) { 59 setCaretPosition(elem, currentPos - 1); 60 } else { 61 setCaretPosition(elem, currentPos); 62 } 63 } else { 64 if (!isLastPos) { 65 if (isNextBlank) { 66 setCaretPosition(elem, currentPos + 1); 67 } else { 68 setCaretPosition(elem, currentPos); 69 } 70 } else { 71 setCaretPosition(elem, elem.value.length); 72 } 73 } 74 },0); 75 }); 76 $("input[data-type='acc']").on("keydown", function (e) { 77 //console.log("keyCode=" + window.event.keyCode); 78 isDelete = window.event.keyCode == 8;//标记用户进行删除操作 79 }); 80 81 })