js 将input框中的输入自动转化成半角大写(税号输入框)

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

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

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

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             在文本中搜索文本并将范围的开始和结束点设置为包围搜索字符串。

具体使用可见其他人的文章,地址是:http://www.jb51.net/article/105787.htm

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

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);
 }
});

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • js 将input框中的输入自动转化成半角大写(税号输入框)

    这两天出了这么一个需求,输入税号的时候,需要自动将其转化为半角大写,并且阻止标点符号中文汉字的输入.(下面会有:全半角转换.文本框选中.光标位置判断.设置光标位置 这些内容) 然后我就开始了慢慢查找资料之路. 首先查了全半角的区别以及如何转化. var str = "中文;:a"; for (var i = 0; i < str.length; i++) { if (str[i].match(/[\u0000-\u00ff]/)) { console.log("半角字符

  • js限制input标签中只能输入中文

    方法很简单,这里就不多BB了,直接奉上示例 <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>只能输入中文</title> </head> <body> <input type="text" id="text"

  • js实现input框文字动态变换显示效果

    本文实例讲述了js实现input框文字动态变换显示效果.分享给大家供大家参考.具体如下: 这里演示js实现INPUT框中的特殊显示效果,一些文字慢慢交替显示,最终显示出完整的文字,需要显示的文字预先保存在数组中,依次调用显示,有意思吧. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-input-txt-rand-show-codes/ 具体代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML

  • 将input框中输入内容显示在相应的div中【三种方法可选】

    例题一枚:在input框中输入内容,会相应的显示在下面的div中的不同做法: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" type="text/css" href="css/bootstrap.css" rel=

  • input框中自动展示当前日期yyyy/mm/dd的实现方法

    直接上代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>input框中自动展示当前日期</title> </head> <body> <input type="text" id="input"> <script>

  • js实现文本框中输入文字页面中div层同步获取文本框内容的方法

    本文实例讲述了js实现文本框中输入文字页面中div层同步获取文本框内容的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.o

  • js实现文本框只允许输入数字并限制数字大小的方法

    本文实例讲述了js实现文本框只允许输入数字并限制数字大小的方法.分享给大家供大家参考.具体如下: 这是一个很个性的输入框特效,规定文本框只允许输入数字,如果你执意要输入其它的字符,则输入的字符将自动消失,除非你输入的是规定内的字符格式,并且对输入数字大小也有限制!为保证兼容性,请使用火狐浏览器. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-input-limit-num-codes/ 具体代码如下: <!DOCTYPE html PUB

  • input框中的name和id的区别

    1. 可以说几乎每个做过Web开发的人都问过,到底元素的ID和Name有什么区别阿?为什么有了ID还要有Name呢?! 而同样我们也可以得到最classical的答案:ID就像是一个人的身份证号码,而Name就像是他的名字,ID显然是唯一的,而Name是可以重复的. 上周我也遇到了ID和Name的问题,在页面里输入了一个input type="hidden",只写了一个ID='SliceInfo',赋值后submit,在后台用Request.Params["SliceInfo

  • 微信小程序登录时如何获取input框中的内容

    这篇文章主要介绍了微信小程序登录时如何获取input框中的内容,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 最近写小程序项目遇到一些问题,今天整理下这些问题的解决方法,希望对用户有帮助.下面是登录页,点击登录时获取input框中的值, 效果如下: wxml布局如下: <view > <input type="text" placeholder-style="color:#fff;" bindin

  • js判断文本框剩余可输入字数的方法

    本文实例讲述了js判断文本框剩余可输入字数的方法.分享给大家供大家参考.具体如下: 目的:为了更直观的体现用户在文本框输入文本时能看到自己输入了多少字,项目中需要通过判断提示文本框剩余可输入字数 JS实现方法 复制代码 代码如下: <html>  <head runat="server">      <title></title>      <script type="text/javascript"> 

随机推荐