这两天出了这么一个需求,输入税号的时候,需要自动将其转化为半角大写,并且阻止标点符号中文汉字的输入。(下面会有:全半角转换、文本框选中、光标位置判断、设置光标位置 这些内容)

然后我就开始了慢慢查找资料之路。


首先查了全半角的区别以及如何转化。

var str = "中文;;a";
for (var i = 0; i < str.length; i++) {
if (str[i].match(/[\u0000-\u00ff]/)) {
console.log("半角字符");
} else if (str[i].match(/[\uff00-\uffff]/)) {
console.log("全角字符 " + str[i] + " " + toSBC(str[i]));
} else {
console.log(str[i]);
// 除了数字英文之外的文本,包括中文等各国文字。
}
}

这是两者的区别,将文字转成unicode之后,进行比较即可,两者均有自己的范围,半角为0x20~0x7E,全角为0xFF01~0xFF5E。(这是16进制,前面的0x是代表是16进制)

转化的话除了空格不同之外,其他均为全角-半角=65248(0xFEE0)

具体的转化函数如下:(这是网上的一种比较靠谱的方法,但是网上的方法普遍把SBC和DBC写反了,我这里纠正了一下。)

//  转全角字符
function toSBC(str) {
var result = "";
var len = str.length;
for (var i = 0; i < len; i++) {
var cCode = str.charCodeAt(i);
//全角与半角相差(除空格外):65248(十进制)
cCode = (cCode>=0x0021 && cCode<=0x007E)?(cCode + 65248) : cCode;
//处理空格
cCode = (cCode==0x0020)?0x03000:cCode;
result += String.fromCharCode(cCode);
}
return result;
}
// 转半角字符
function toDBC(str) {
var result = "";
var len = str.length;
for (var i = 0; i < len; i++) {
var cCode = str.charCodeAt(i);
//全角与半角相差(除空格外):65248(十进制)
cCode = (cCode>=0xFF01 && cCode<=0xFF5E)?(cCode - 65248) : cCode;
//处理空格
cCode = (cCode==0x03000)?0x0020:cCode;
result += String.fromCharCode(cCode);
}
return result;
}

全角半角的区别也找完了,开始想办法转化,用的是input方法。

var oldValue = "";
var $thisDom; // 假装有jquery的dom元素
$thisDom.unbind().bind("input", function (e) {
var reg = /^[0-9A-Za-z]*$/;
var str = toDBC(e.target.value).toUpperCase();
if (reg.test(str)) {
oldValue = str;
$(this).val(str);
} else {
$(this).val(oldValue);
}
});

但是有一个问题,那就是光标有问题,始终在最后一位输入的时候没问题,但是在中间输入,光标始终会跳到最后一位。于是又有了下面的光标相关知识。


在网上找到了下列相关代码,用来控制光标位置。

function getCursortPosition(ctrl){
var CaretPos = 0;
if (document.selection) {
ctrl.focus();
var Sel = document.selection.createRange();
Sel.moveStart('character', -ctrl.value.length);
CaretPos = Sel.text.length;
} else if (ctrl.selectionStart || ctrl.selectionStart == '0') {
CaretPos = ctrl.selectionStart;
}
return (CaretPos);
} function setCaretPosition(ctrl, pos){
if (ctrl.setSelectionRange) {
ctrl.focus();
ctrl.setSelectionRange(pos, pos);
} else if (ctrl.createTextRange) {
var range = ctrl.createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
}

这两个分别是获取光标位置以及设置光标位置。这里用到的是textRange对象。

TextRange对象是动态HTML(DHTML)的高级特性,使用它可以实现很多和文本有关的任务,例如搜索和选择文本。文本范围让您可以选择性的将字符、单词和句子从文档中挑选出来。TextRange对象是在HTML文档将要显示的文本流上建立开始和结束位置的抽象对象。

下面是TextRange的常用属性与方法:

属性:
boundingHeight   获取绑定TextRange对象的矩形的高度
boundingLeft       获取绑定TextRange 对象的矩形左边缘和包含TextRange对象的左侧之间的距离
offsetLeft            获取对象相对于版面或由offsetParent属性指定的父坐标的计算左侧位置
offsetTop            获取对象相对于版面或由offsetParent属性指定的父坐标的计算顶端位置
htmlText            获取绑定TextRange对象的矩形的宽度
text                   设置或获取范围内包含的文本
方法:
moveStart          更改范围的开始位置
moveEnd            更改范围的结束位置
collapse             将插入点移动到当前范围的开始或结尾
move                折叠给定文本范围并将空范围移动给定单元数
execCommand   在当前文档、当前选中区或给定范围上执行命令
select                将当前选择区置为当前对象
findText             在文本中搜索文本并将范围的开始和结束点设置为包围搜索字符串。

具体使用可见其他人的blog,地址是:http://www.cnblogs.com/poissonnotes/archive/2010/04/15/1712903.html  或者  http://www.dengzhr.com/js/1013?utm_source=tuicool&utm_medium=referral

回到正题,于是我把上述代码拼进了我的代码中。

function toDBC(str) {
var result = "";
var len = str.length;
for (var i = 0; i < len; i++) {
var cCode = str.charCodeAt(i);
//全角与半角相差(除空格外):65248(十进制)
cCode = (cCode>=0xFF01 && cCode<=0xFF5E)?(cCode - 65248) : cCode;
//处理空格
cCode = (cCode==0x03000)?0x0020:cCode;
result += String.fromCharCode(cCode);
}
return result;
} function getCursortPosition(ctrl){
var CaretPos = 0;
if (document.selection) {
ctrl.focus();
var Sel = document.selection.createRange();
Sel.moveStart('character', -ctrl.value.length);
CaretPos = Sel.text.length;
} else if (ctrl.selectionStart || ctrl.selectionStart == '0') {
CaretPos = ctrl.selectionStart;
}
return (CaretPos);
} function setCaretPosition(ctrl, pos){
if (ctrl.setSelectionRange) {
ctrl.focus();
ctrl.setSelectionRange(pos, pos);
} else if (ctrl.createTextRange) {
var range = ctrl.createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
} var oldValue = this.model.get("taxNo");
$taxNoDom.unbind().bind("input", function (e) {
var reg = /^[0-9A-Za-z]*$/;
var position = getCursortPosition($taxNoDom[0]);
var str = toDBC(e.target.value).toUpperCase();
if (reg.test(str) && str.length <= 25) {
oldValue = str;
$(this).val(str);
setCaretPosition($taxNoDom[0], position);
} else {
$(this).val(oldValue);
setCaretPosition($taxNoDom[0], position - 1);
}
});

上述代码中我自己写的就是最下面的绑定事件,仔细看一下应该都是可以看懂的。但是上述代码有一个bug,其实也算是getCursortPosition这个方法的bug。

那就是在中文输入法的时候,输入的字母在input事件执行的时候是选中格式,光标在该字母之前,以至于位置跟想象的有偏差,在正确的时候打出来的字一直在光标之后。

当时我很苦恼感觉人生无望啊。。想了几种方法:

1. 默认触发键盘左箭头再触发右箭头。这样不管是不是选中光标都应该是正确的位置了。

2. 查看当前页面中是否有选中的文字。如果有选中的文字,就把返回的光标位置+1。

网上查了一下第一种方法,立马就放弃了。相关资料也很少,而且局限性相当大,浏览器之间差异也大,怎么看都不像是会是一种好方法。

然后找到了第二种方法的方法。window.getSelection和document.selection

IE9以下支持:document.selection

IE9、Firefox、Safari、Chrome和Opera支持:window.getSelection()

(由于我们公司项目只支持ie9及以上,就没有尝试document.selection)

我自己试了一下,如果有选中的文字的时候window.getSelection().type === "Range",如果没有选中window.getSelection().type === "Caret"。

于是最终的代码如下:

function toDBC(str) {
var result = "";
var len = str.length;
for (var i = 0; i < len; i++) {
var cCode = str.charCodeAt(i);
//全角与半角相差(除空格外):65248(十进制)
cCode = (cCode>=0xFF01 && cCode<=0xFF5E)?(cCode - 65248) : cCode;
//处理空格
cCode = (cCode==0x03000)?0x0020:cCode;
result += String.fromCharCode(cCode);
}
return result;
} function getCursortPosition(ctrl){
var CaretPos = 0;
if (document.selection) {
ctrl.focus();
var Sel = document.selection.createRange();
Sel.moveStart('character', -ctrl.value.length);
CaretPos = Sel.text.length;
} else if (ctrl.selectionStart || ctrl.selectionStart == '0') {
if (window.getSelection().type === "Range") {
CaretPos = ctrl.selectionStart + 1;
} else {
CaretPos = ctrl.selectionStart;
}
}
return (CaretPos);
} function setCaretPosition(ctrl, pos){
if (ctrl.setSelectionRange) {
ctrl.focus();
ctrl.setSelectionRange(pos, pos);
} else if (ctrl.createTextRange) {
var range = ctrl.createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
} var oldValue = this.model.get("commercialTax").taxNo;
$taxNoDom.unbind().bind("input", function (e) {
var reg = /^[0-9A-Za-z]*$/;
var position = getCursortPosition($taxNoDom[0]);
var str = toDBC(e.target.value).toUpperCase();
if (reg.test(str) && str.length <= 25) {
oldValue = str;
$(this).val(str);
setCaretPosition($taxNoDom[0], position);
} else {
$(this).val(oldValue);
setCaretPosition($taxNoDom[0], position - 1);
}
});

发现在一家公司只要自己多包揽一些活,积极一些,总会有非常多的东西可以学习的~2017加油~~

税号输入框 将input框中的输入自动转化成半角大写的更多相关文章

  1. input框中自动展示当前日期 yyyy/mm/dd

    直接上代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  2. 解决input框中加入disabled="disabled"之后,改变字体的颜色(默认的是灰色)

    在input框中加入disabled="disabled"之后,字体默认的就变成灰色了 解决方案 input[disabled]{color:#fff;opacity:1} dis ...

  3. js/jquery 获取本地文件的文件路劲 获取input框中type=‘file’ 中的文件路径(转载)

     原文:http://blog.csdn.net/niyingxunzong/article/details/16989947 js/jquery 获取本地文件的文件路劲 获取input框中type= ...

  4. 小程序登录时如何获取input框中的内容

    最近写小程序项目遇到一些问题,今天整理下这些问题的解决方法,希望对用户有帮助.下面是登录页,点击登录时获取input框中的值, 效果如下: wxml布局如下: <view > <in ...

  5. 控制input标签中只能输入数字以及小数点后两位

    js 代码如下: /* 控制input标签中只能输入数字 和小数点后两位 */ function checkNum(obj) { //检查是否是非数字值 if (isNaN(obj.value)) { ...

  6. js—input框中输入数字,动态生成内容的方法

    项目中需要在前端实现: 用户输入数字n,动态生成n个元素,删除n,自动清空n个元素(如图一): 用户输入数字n,失焦生成n个元素,再聚焦修改n,自动清空n个元素(如图二): 图一: 图二: 需求一实现 ...

  7. bootstrap在input框中加入icon图标

    <form class="form-horizontal"> <div class="form-group has-feedback"> ...

  8. input框只允许输入正整数、正数(包含小数)的解决方法 vue.js实现

    我来打自己脸了!!!!...刚刚发现在中文输入法下是无效的,有人能解决这个问题么 如果要求input只能输入数字怎么做? 设置type="number" ? 那我如果想限制长度,此 ...

  9. python WEB UI自动化在日期框中动态输入当前日期

    要在日期框中输入当前日期,如下图 代码为 本想用最简单的方法,直接用sendkeys发送当前日期,如下: current_time=time.strftime('%Y-%m-%d',time.loca ...

随机推荐

  1. jquery中(function($){...})(jQuery)是什么

    调用函数 时,是在函数后面写上括号和实参的,由于操作符的优先级,函数本身也需要用括号,即:(function(arg){...})(param)而(function($){...}) (jQuery) ...

  2. 试水mongodb er

    1)data ready var a = {"name":"zhekou","CharDate":"2015-12-01" ...

  3. git 常用命令--Linus Torvalds

    1.git log 显示仓库的历史记录,默认显示所有记录, 1)git log -m,显示最近的几次提交,, 2)git log --pretty=oneline  显示提交hash和注释 -p 按补 ...

  4. css--用户体验笔记及兼容记录

    css用户体验 1.HTML的< >&"©分别是<,>,&,",©;的转义字符 2.IE8和7的透明度 filter: progid:DXI ...

  5. IOS开发-UI学习-UITextField的各种属性设置

    UITextField是IOS中非常常用的一个控件,用来接收用户输入信息,完成应用和用户的交互.它的主要属性设置如下: //初始化textfield并设置位置及大小 UITextField *text ...

  6. win7下sublime text3 安装Emmet的pyv8

    1.通过快捷键 ctrl+` 或者 View > Show Console 菜单打开控制台 2.适用于 Sublime Text 3: import urllib.request,os;pf=' ...

  7. 【转】安卓Fragment不完全介绍

    转两篇博客: 1.http://blog.csdn.net/lmj623565791/article/details/37970961 2.http://blog.csdn.net/lmj623565 ...

  8. 安装pip工具

    Python 2.7.9+ and 3.4+ Good news! Python 3.4 (released March 2014) and Python 2.7.9 (released Decemb ...

  9. UVa 11503 - Virtual Friends

    题目大意:给出若干对朋友关系,每给出一对朋友关系,就输出二者所在关系网中的人数. 首先是对每个人编号,使用map简化编号过程,然后就是使用并查集更新集合.要注意的是当给出A和B的朋友关系时,无论A和B ...

  10. IE6下完美兼容css3圆角和阴影属性的htc插件PIE.htc

    1.(推荐:)css插件PIE.htc,这个才是真正完美兼容css3的圆角和阴影属性在IE6环境下使用的效果,但要注意的是:下面的代码必须写在html文件的head标签内,否则无效(不能从外部引用下面 ...