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 相关文章推荐
使用GruntJS构建Web程序之构建篇
Jun 04 Javascript
JS+CSS实现表格高亮的方法
Aug 05 Javascript
详解 javascript中offsetleft属性的用法
Nov 11 Javascript
canvas实现图片根据滑块放大缩小效果
Feb 24 Javascript
JS三目运算(三元运算)方法详解
Mar 01 Javascript
10道典型的JavaScript面试题
Mar 22 Javascript
分享ES6的7个实用技巧
Jan 18 Javascript
JS实现百度搜索接口及链接功能实例代码
Feb 02 Javascript
Javascript的this详解
Mar 23 Javascript
Node.js fs模块(文件模块)创建、删除目录(文件)读取写入文件流的方法
Sep 03 Javascript
Angular value与ngValue区别详解
Nov 27 Javascript
VSCode 添加自定义注释的方法(附带红色警戒经典注释风格)
Aug 27 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
php读取数据库信息的几种方法
2008/05/24 PHP
PHP 函数call_user_func和call_user_func_array用法详解
2014/03/02 PHP
PHP中把错误日志保存在系统日志中(Windows系统)
2015/06/23 PHP
php通过curl添加cookie伪造登陆抓取数据的方法
2016/04/02 PHP
Opacity.js
2007/01/22 Javascript
javascript打开新窗口同时关闭旧窗口
2009/01/16 Javascript
javascript CSS画图之基础篇
2009/07/29 Javascript
JS读取cookies信息(记录用户名)
2012/01/10 Javascript
微信小程序上滑加载下拉刷新(onscrollLower)分批加载数据(一)
2017/05/11 Javascript
Node4-5静态资源服务器实战以及优化压缩文件实例内容
2019/08/29 Javascript
JS回调函数 callback的理解与使用案例分析
2019/09/09 Javascript
file-loader打包图片文件时路径错误输出为[object-module]的解决方法
2020/01/03 Javascript
[04:13]2018国际邀请赛典藏宝瓶Ⅱ饰品一览
2018/07/21 DOTA
python 性能优化方法小结
2017/03/31 Python
Python实现的栈(Stack)
2018/01/26 Python
python3+PyQt5泛型委托详解
2018/04/24 Python
Python中xml和json格式相互转换操作示例
2018/12/05 Python
python版百度语音识别功能
2019/07/09 Python
react+django清除浏览器缓存的几种方法小结
2019/07/17 Python
如何安装2019Pycharm最新版本(详细教程)
2019/09/26 Python
python垃圾回收机制(GC)原理解析
2019/12/30 Python
Python爬虫代理池搭建的方法步骤
2020/09/28 Python
携程英文网站:Trip.com
2017/02/07 全球购物
西安当代医院管理研究院笔试题
2015/12/11 面试题
应届毕业生专业个人求职自荐信格式
2013/11/20 职场文书
主治医师岗位职责
2013/12/10 职场文书
大学生创业计划书的范文
2014/01/07 职场文书
小学节能减排倡议书
2014/05/15 职场文书
禁止酒驾标语
2014/06/25 职场文书
小学生感恩老师演讲稿
2014/08/28 职场文书
有子女的离婚协议书怎么写(范本)
2014/09/29 职场文书
小学生通知书评语
2014/12/31 职场文书
亲属关系公证书样本
2015/01/23 职场文书
世界水日宣传活动总结
2015/02/09 职场文书
Python爬虫之爬取二手房信息
2021/04/27 Python
基于Redis实现分布式锁的方法(lua脚本版)
2021/05/12 Redis