javascript限制文本框只允许输入数字(曾经与现在的方法对比)


Posted in Javascript onJanuary 18, 2013

很多时候需要用到限制文本框的数字输入,试过许多方法,都不太理想,遂决定自己实现一个来玩玩。

曾经使用过的方法

通过onkeydown事件来控制只允许数字:

<input onkeydown="return event.keyCode>=48&&event.keyCode<=57||event.keyCode>=96&&event.keyCode<=105" />

通过jQuery插件Masked Input:http://digitalbush.com/projects/masked-input-plugin/
通过jQuery插件MeioMask:https://github.com/fabiomcosta/jquery-meiomask
onkeydown事件控制起来相对比较麻烦,上面的简化版很多键都没有涉及到,操作体验比较糟糕。
jQuery的两个插件使用起来还是比较灵活的,能够满足大部分需要,但是在控制输入长度上限制的很不灵活(或许是我没有发现灵活的使用方式?)

具体实现方法
使用maskedInput里的一部分方法来提取光标位置
使用stackoverflow上提供的通用方法来处理键盘的敲击:http://stackoverflow.com/questions/469357/html-text-input-allow-only-numeric-input
更新:参考http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes上列出的keycode
然后再自定义两个属性来设置输入的数字、小数长度:
•data-numbers控制数字输入的长度
•data-decimals控制小数输入的长度
最终全部代码实现如下:

function validateDigitsOnly(evt) { 
var e = evt || window.event, 
key = e.keyCode || e.which; 
if ( 
// Backspace, Tab, Enter, Esc, Delete 
key == 8 || key == 9 || key == 13 || key == 27 || key == 46 || 
// Ctrl + A 
(key == 65 && event.ctrlKey === true) || 
// Home, End, 四个方向键 
key >= 35 && key <= 40) { 
return; 
} 
if (e.shiftKey || e.altKey || e.ctrlKey) { 
return false; 
} 
var el = e.target || e.srcElement, 
// 最大数字长度 
nl = el.getAttribute("data-numbers") || 15, 
// 最大小数长度 
dl = el.getAttribute("data-decimals") || 2, 
val = el.value, 
// "." 位置 
dotIndex = val.indexOf("."), 
rng = caret.call(el), 
// 光标在"."左边 
rLeft = rng.end <= dotIndex, 
// 光标在"."右边 
rRight = rng.begin > dotIndex; 
if ( 
// 数字 
key >= 48 && key <= 57 || 
// 数字键盘输入的数字 
key >= 96 && key <= 105) { 
if (validateValue(dotIndex, val, rLeft, rRight, nl, dl)) 
return; 
// 选中部分文本再做一次处理 
val = val.substring(0, rng.begin) + val.substring(rng.end); 
dotIndex = val.indexOf("."); 
if (validateValue(dotIndex, val, rLeft, rRight, nl, dl)) 
return; 
} 
else if ( 
// ".", "," 
(key == 190 /*|| key == 188*/ || 
// 数字键盘上的 ".", "," 
key == 110/*|| key == 109*/) && 
// 允许输入小数 
dl > 0) { 
if ( 
// 未输入".", 且输入的位置后面的小数位数未达到上限 
dotIndex == -1 && (rng.end == val.length || val.substring(rng.end).length <= dl) || 
// 输过".", 且选中部分文本包含"." 
dotIndex > -1 && rng.begin <= dotIndex && dotIndex < rng.end) 
return; 
} 
return false; 
} 
// 验证输入的值 
function validateValue(dotIndex, val, rLeft, rRight, nl, dl) { 
if ( 
// 未输入过"." 
dotIndex == -1 && val.length < nl || 
// 光标位置在"."之前 
rLeft && val.substring(0, dotIndex).length < nl || 
// 光标在"."之后且未达到小数上限 
rRight && val.substring(dotIndex + 1).length < dl) 
return true; 
return false; 
} 
// 获取光标位置 
function caret() { 
var begin, end; 
if (this.setSelectionRange) { 
begin = this.selectionStart; 
end = this.selectionEnd; 
} else if (document.selection && document.selection.createRange) { 
var range = document.selection.createRange(); 
begin = 0 - range.duplicate().moveStart('character', -100000); 
end = begin + range.text.length; 
} 
return { begin: begin, end: end }; 
}

使用方法
具体使用方法如下:
<input type="text" id="t1" /> 
<input type="text" id="t2" data-numbers="5" data-decimals="4" /> 
<script> 
document.getElementById("t1").onkeydown = validateDigitsOnly; 
document.getElementById("t2").onkeydown = validateDigitsOnly; 
</script>

或者干脆写在html里:
<input type="text" id="lwme_text_3" onkeydown="return validateDigitsOnly(event)" />

如果引入jQuery的话使用起来就更加简单了:
<input type="text" class="digitsOnly" />

$(".digitsOnly").keydown(validateDigitsOnly);

结尾
这个方法虽然有些地方效率还不够高,而且某些键盘key的还未处理,也不排除某些情况下可能失效,但是对于大多数情况下使用已经足够了。
大家若有额外需要请自行修改,当然有更好的办法也请分享(*^__^*)
over
PS:01.18更新了一些keyCode的判断,以及错把110写成109≡(???)≡
另外需要注意:对于使用右键菜单或者是菜单栏粘贴进来的需要额外处理
还有一种极端的情况:在网页中选中文字并拖动到文本框内,或者是在文本框中选中文字并拖动,这都需要做额外处理
对于以上两种需要额外处理的情况,比较便捷的方法是加一个验证,比如jQuery.validate之类的表单验证,否则处理起来比较麻烦
再PS:在win8下,切换到微软拼音可能会造成无法输入,不知道其他系统或者其他输入法有没有这个问题( *_*) (`~~`) ====
Javascript 相关文章推荐
jquery 合并内容相同的单元格(示例代码)
Dec 13 Javascript
使用javascript实现json数据以csv格式下载
Jan 09 Javascript
javascript实现确定和取消提示框效果
Jul 10 Javascript
jquery合并表格中相同文本的相邻单元格
Jul 17 Javascript
浅析jQuery Ajax通用js封装
Jun 22 Javascript
JavaScript数组方法大全(推荐)
Jul 05 Javascript
KnockoutJS 3.X API 第四章之数据控制流if绑定和ifnot绑定
Oct 10 Javascript
详解Angular 4.x Injector
May 04 Javascript
获取url中用&amp;隔开的参数实例(分享)
May 28 Javascript
Parcel 打包示例(React HelloWorld)
Jan 16 Javascript
详解webpack引入第三方库的方式以及注意事项
Jan 15 Javascript
JavaScript中10个Reduce常用场景技巧
Jun 21 Javascript
js replace正则表达式应用案例讲解
Jan 17 #Javascript
Javascript模块化编程(三)require.js的用法及功能介绍
Jan 17 #Javascript
Javascript模块化编程(一)AMD规范(规范使用模块)
Jan 17 #Javascript
Javascript模块化编程(一)模块的写法最佳实践
Jan 17 #Javascript
Javascript异步编程的4种方法让你写出更出色的程序
Jan 17 #Javascript
jQuery链式操作如何实现以及为什么要用链式操作
Jan 17 #Javascript
JQuery中根据属性或属性值获得元素(6种情况获取方法)
Jan 17 #Javascript
You might like
WIN98下Apache1.3.14+PHP4.0.4的安装
2006/10/09 PHP
PHP使用GIFEncoder类生成的GIF动态图片验证码
2014/07/01 PHP
PHP实现文件下载断点续传详解
2014/10/15 PHP
php判断访问IP的方法
2015/06/19 PHP
php提高网站效率的技巧
2015/09/29 PHP
THINKPHP在添加数据的时候获取主键id的值方法
2017/04/03 PHP
laravel自定义分页的实现案例offset()和limit()
2019/10/15 PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
2020/04/05 PHP
图片之间的切换
2006/06/26 Javascript
excel操作之Add Data to a Spreadsheet Cell
2007/06/12 Javascript
JS图片预加载 JS实现图片预加载应用
2012/12/03 Javascript
js去除空格的12种实用方法
2013/11/08 Javascript
js中事件的处理与浏览器对象示例介绍
2013/11/29 Javascript
JavaScript实现的encode64加密算法实例分析
2015/04/15 Javascript
JS实现自动固定顶部的悬浮菜单栏效果
2015/09/16 Javascript
javascript编程异常处理实例小结
2015/11/30 Javascript
关于vue-resource报错450的解决方案
2017/07/24 Javascript
Javascript中toFixed计算错误(依赖银行家舍入法的缺陷)解决方法
2017/08/22 Javascript
jquery应用实例分享_实现手风琴特效
2018/02/01 jQuery
Vue实现动态创建和删除数据的方法
2018/03/17 Javascript
vue 父组件给子组件传值子组件给父组件传值的实例代码
2019/04/15 Javascript
python关闭windows进程的方法
2015/04/18 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
2018/04/23 Python
python 按不同维度求和,最值,均值的实例
2018/06/28 Python
美国女鞋品牌:naturalizer(娜然)
2016/08/01 全球购物
苹果Mac升级:MacSales.com
2017/11/20 全球购物
说出数据连接池的工作机制是什么?
2013/04/19 面试题
销售人员自我评价怎么写
2013/09/19 职场文书
毕业生找工作的求职信范文
2013/12/24 职场文书
项目经理任命书内容
2014/06/06 职场文书
安全标语口号
2014/06/09 职场文书
2014大学生职业生涯规划书最新范文
2014/09/13 职场文书
教师师德师风整改措施
2014/10/24 职场文书
导游词之绍兴柯岩古镇
2020/01/09 职场文书
浅析Python实现DFA算法
2021/06/26 Python
MySQL数据库之存储过程 procedure
2022/06/16 MySQL