window.onload =function() {
document.getElementById("input_num").oninput =function() {
this.value =this.value.replace(/\s/g,'').replace(/\D/g,'').replace(/(\d{})(?=\d)/g,"$1 ");;
};
};

方案一: 缺点,光标不能定位

handleKeyUp = () => {
const target = document.getElementsByClassName('cardNumber')[].firstChild
target.onkeyup = e => {
// 只对输入数字时进行处理
if ((e.which >= && e.which <= ) ||
(e.which >= && e.which <= )) {
// 获取当前光标的位置
const caret = target.selectionStart
// 获取当前的value
const value = target.value
// 从左边沿到坐标之间的空格数
const sp = (value.slice(, caret).match(/\s/g) || []).length
// 去掉所有空格
const nospace = value.replace(/\s/g, '')
// 重新插入空格
const curVal = target.value = nospace.replace(/(\d{})/g, '$1 ').trim()
// 从左边沿到原坐标之间的空格数
const curSp = (curVal.slice(, caret).match(/\s/g) || []).length
// 修正光标位置
target.selectionEnd = target.selectionStart = caret + curSp - sp
}
}
}

方案二: 缺点(某些浏览器不工作,部分浏览器删除时光标跳动,如支付宝默认浏览器)

let isDelete = false; // globle param
// getCursortPosition
const getCursortPosition = (textDom) => {
let cursorPos =
if (document.selection) { // ie 10 9 8 7 6 5
// IE Support
textDom.focus()
let selectRange = document.selection.createRange()
selectRange.moveStart('character', -textDom.value.length)
cursorPos = selectRange.text.length
} else if (textDom.setSelectionRange) { // ie 11 10 9 ff safiri chrome
// webkit support
textDom.focus()
cursorPos = textDom.selectionStart
}
return cursorPos
} // setCursorPosition
const setCursorPosition = (textDom, pos) => {
if (textDom.setSelectionRange) {
textDom.focus()
textDom.setSelectionRange(pos, pos)
} else if (textDom.createTextRange) {
// IE Support
const range = textDom.createTextRange()
range.collapse(true)
range.moveEnd('character', pos)
range.moveStart('character', pos)
range.select()
}
} export const handleKeyUp = target => {
target.onkeyup = () => {
const elem = target
//for some andriod system keyboard can not input (eg: vivo)
setTimeout(() => {
const str = elem.value
let currentPos = getCursortPosition(elem)
let posAfterText = ''
let posPreText = ''
let isNextBlank = false//the next is blank or not
let isPreBlank = false
let isLastPos = true
if (currentPos != str.length) { // not the last one
posAfterText = str.substr(currentPos, )
posPreText = str.substr(currentPos - , )
isNextBlank = /^\s+$/.test(posAfterText)
isPreBlank = /^\s+$/.test(posPreText)
isLastPos = false
}
if (elem.value.length <= ) { // maxlength
elem.value = elem.value.replace(/\s/g, '').replace(/(\w{})(?=\w)/g, '$1 ')
}
if (isDelete) {
if (isPreBlank) {
setCursorPosition(elem, currentPos - )
} else {
setCursorPosition(elem, currentPos)
}
} else if (!isLastPos) {
if (isNextBlank) {
setCursorPosition(elem, currentPos + )
} else {
setCursorPosition(elem, currentPos)
}
} else {
setCursorPosition(elem, elem.value.length)
}
}, )
}
} export const handleKeyDown = target => {
target.onkeydown = () => {
isDelete = window.event.keyCode == // the flag of delete
}
}

方案三,比较完美的解决方案,支持各种终端浏览器输入, 任意位置删除输入且光标不会跳动。

export const getCursorPosition = textDom => {
let cursorPos =
if (textDom.setSelectionRange) {
// webkit support
textDom.focus()
cursorPos = textDom.selectionStart
}
return cursorPos
} export const setCursorPosition = (textDom, pos) => {
if (textDom.setSelectionRange) {
textDom.focus()
textDom.setSelectionRange(pos, pos)
}
} const handleKeyUp = e => {
const { target } = e
const elem = target
// for some andriod system keyboard can not input (eg: vivo)
setTimeout(() => {
const str = elem.value
const currentPos = getCursorPosition(elem)
let posAfterText = ''
let posPreText = ''
let isNextBlank = false// the next is blank or not
let isPreBlank = false
let isLastPos = true
if (currentPos !== str.length) { // not the last one
posAfterText = str.substr(currentPos, )
posPreText = str.substr(currentPos - , )
isNextBlank = /^\s+$/.test(posAfterText)
isPreBlank = /^\s+$/.test(posPreText)
isLastPos = false
}
if (elem.value.length <= ) { // maxlength
elem.value = elem.value.replace(/\s/g, '').replace(/(\w{})(?=\w)/g, '$1 ')
}
if (e.keyCode === ) { // delete key
if (isPreBlank) {
setCursorPosition(elem, currentPos - )
} else {
setCursorPosition(elem, currentPos)
}
} else if (!isLastPos) {
if (isNextBlank) {
setCursorPosition(elem, currentPos + )
} else {
setCursorPosition(elem, currentPos)
}
} else {
setCursorPosition(elem, elem.value.length)
}
}, )
}

方案三(优化方案, 不支持低版本ie, 支持低版本ie见方案三)

js实现卡号每四位空格分隔的更多相关文章

  1. js验证身份证号,超准确

    js验证身份证号,超准确 看程序前先来了解下身份证号的构成:身份证号分为两种,旧的为15位,新的为18位.身份证15位编码规则:dddddd yymmdd xx p    其中 dddddd:地区码  ...

  2. sqlserver卡号段分组

    之前给上海一家电子商务公司做一个卖卡系统,遇到了卡号段分组的问题.刚开始没什么好的实现方法,遂在博客园求助但未果,没法自己研究sql,终于搞定. 问题描述: 有个卡库存表,有个卡号字段,假设数据:16 ...

  3. C++中int转为char 以及int 转为string和string 转int和空格分隔字符串

    1.对于int 转为char 直接上代码: 正确做法: void toChar(int b) { char u; ]; _itoa( b, buffer, ); //正确解法一 u = buffer[ ...

  4. 金蝶核算项目余额表卡号余额与天财商龙CRM卡号余额对比

    金蝶核算项目余额表卡号余额与天财尚龙CRM卡号余额对比 由于历史遗留问题,财务一直不调账,修改核算科目卡号与天财商龙CRM系统一直,只能用VBA把卡号前缀修改成两边一致. 再通过,Power BI D ...

  5. highlight.js 设置行号

    原文地址:highlight.js 设置行号 博客地址:http://www.extlight.com 一.背景 笔者在开发这套博客系统时使用 Editormd 作为 Markdown 编辑器,由于不 ...

  6. Linux下读取RFID卡号(C串口编程)

    由于项目需要用到RFID.GPRS.摄像头等模块所以便看了一下,整理了一下学习思路,本篇先是整理一下串口读取RFID卡号的程序思路,后面还会更其他的 RFID模块: 本次采用的是125K的RFID读卡 ...

  7. .net第三方数据库物理卡号同步功能实现

    本地数据库用的是Oracle,第三方数据库是SQL Server,连接字符串保存在web.config里面. 第三方数据库为增量,每次读取要记录读取的最大位置.我是保存在本地txt文件里面. //保存 ...

  8. Xamarin如何使用终端设备的NFC功能传递卡号等信息给Web页面(Android)

    一.前提条件,App必须具有NFC权限. 二.项目中加入监控类NFCCatchActivity.cs [Activity(Label = "NFCCatch",Theme = &q ...

  9. vue实现一个会员卡的组件(可以动态传入图片(分出的一个组件)、背景、文字、卡号等)

    自己在写这个组件的时候主要遇到的问题就是在动态传入背景图片或者背景色的时候没能立马顺利写出来,不过现在实现了这个简单组件就和大家分享一下 <template> <div class= ...

随机推荐

  1. LeetCode: Permutations 解题报告

    Permutations Given a collection of numbers, return all possible permutations. For example,[1,2,3] ha ...

  2. SQLAlchemy数据库连接和初始化数据库

    查看版本 >>> import sqlalchemy >>> sqlalchemy.__version__ '1.0.9' 创建连接 from sqlclachem ...

  3. Linux kernel 生成 /dev/spidev*

    最近在调试一个 spi 转 4 路uart 的设备 先从spi 底层开始做起 kernel make menuconfig Device Drivers ---> [*] SPI support ...

  4. JDBC 查询的三大参数 setFetchSize prepareStatement(String sql, int resultSetType, int resultSetConcur)

    JDBC 查询的三大参数 本文转载至 http://blog.csdn.net/turkeyzhou/article/details/5115228 DBC1.0 .JDBC2.0 .JDBC3.0  ...

  5. SpringMVC 利用AbstractRoutingDataSource实现动态数据源切换

    SpringMVC 利用AbstractRoutingDataSource实现动态数据源切换 本文转载至:http://exceptioneye.iteye.com/blog/1698064 Spri ...

  6. Entity Framework管理实体关系(一):管理一对一关系

    我们现在已经知道如何使用Code First来定义简单的领域类,并且如何使用DbContext类来执行数据库操作.现在我们来看下数据库理论中的多样性关系,我们会使用Code First来实现下面的几种 ...

  7. MongoDB Shell 了解使用

    配置环境变量 WIN10系统:右键单击"此电脑"--属性--高级系统设置--高级--环境变量,添加C:\Program Files\MongoDB\Server\3.0\bin 如 ...

  8. rufus/scheduler

    之前先在initializers 文件夹下建立了一个task.rb ,rails服务启动的时候执行,本地没问题,可是服务器上启动了3个进程,会执行3遍,解决方法是 把task.rb 放到 script ...

  9. laravel 控制器

    1:如何快速的创建一个控制器 用cmd进入当前的项目名文件夹里面执行如下语句: php artisan  make:controller  HgjController 2:编辑Hgj中的index方法 ...

  10. in 型子查询引出的陷阱

    题: 在ecshop商城表中,查询6号栏目的商品, (注,6号是一个大栏目) 最直观的: mysql> select goods_id,cat_id,goods_name from goods ...