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与iframe交互实现代码
Dec 24 Javascript
理解Javascript_10_对象模型
Oct 16 Javascript
JS设置获取cookies的方法
Jan 26 Javascript
javascript在网页中实现读取剪贴板粘贴截图功能
Jun 07 Javascript
老生常谈onBlur事件与onfocus事件(js)
Jul 09 Javascript
jQuery源码分析之init的详细介绍
Feb 13 Javascript
jquery mobile实现可折叠的导航按钮
Mar 11 Javascript
animate.css在vue项目中的使用教程
Aug 05 Javascript
Vue弹出菜单功能的实现代码
Sep 12 Javascript
详解KOA2如何手写中间件(装饰器模式)
Oct 11 Javascript
jQuery 操作 HTML 元素和属性的方法
Nov 12 jQuery
关于antd tree 和父子组件之间的传值问题(react 总结)
Jun 02 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中执行系统外部命令
2006/10/09 PHP
php adodb分页实现代码
2009/03/19 PHP
PHP解析RSS的方法
2015/03/05 PHP
php从数据库中读取特定的行(实例)
2017/06/02 PHP
php使用ftp实现文件上传与下载功能
2017/07/21 PHP
Laravel如何使用Redis共享Session
2018/02/23 PHP
ThinkPHP框架实现的微信支付接口开发完整示例
2019/04/10 PHP
javascript 极速 隐藏/显示万行表格列只需 60毫秒
2009/03/28 Javascript
关于Aptana Studio生成自动备份文件的解决办法
2009/12/23 Javascript
Jquery AutoComplete自动完成 的使用方法实例
2010/03/19 Javascript
百度移动版的url编码解码示例
2014/04/29 Javascript
jQuery实用技巧必备(下)
2015/11/03 Javascript
Vue.js中数组变动的检测详解
2016/10/12 Javascript
通过示例彻底搞懂js闭包
2017/08/10 Javascript
vue2.0 better-scroll 实现移动端滑动的示例代码
2018/01/25 Javascript
Angularjs实现控制器之间通信方式实例总结
2018/03/27 Javascript
微信小程序云开发(数据库)详解
2019/05/17 Javascript
[01:56]无止竞 再出发——中国军团出征2017年DOTA2国际邀请赛
2017/07/05 DOTA
[01:14:12]2018DOTA2亚洲邀请赛4.7 总决赛 LGD vs Mineski 第二场
2018/04/09 DOTA
在Python中操作文件之read()方法的使用教程
2015/05/24 Python
python制作最美应用的爬虫
2015/10/28 Python
python中的编码知识整理汇总
2016/01/26 Python
Python连接PostgreSQL数据库的方法
2016/11/28 Python
对python dataframe逻辑取值的方法详解
2019/01/30 Python
Python学习笔记之lambda表达式用法详解
2019/08/08 Python
浅谈python print(xx, flush = True) 全网最清晰的解释
2020/02/21 Python
Python多线程操作之互斥锁、递归锁、信号量、事件实例详解
2020/03/24 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
Python通过类的组合模拟街道红绿灯
2020/09/16 Python
英国鞋网:Rubber Sole
2020/03/03 全球购物
项目经理任命书范本
2014/06/05 职场文书
社会工作专业求职信
2014/07/15 职场文书
公司借条范本
2015/05/25 职场文书
忠诚与背叛观后感
2015/06/04 职场文书
导游词之山东八仙过海景区
2019/11/11 职场文书
Python机器学习之底层实现KNN
2021/06/20 Python