很多时候需要用到限制文本框的数字输入,试过许多方法,都不太理想,遂决定自己实现一个来玩玩。 曾经使用过的方法 通过onkeydown事件来控制只允许数字:
- <input onkeydown="return event.keyCode>=48&&event.keyCode<=57||event.keyCode>=96&&event.keyCode<=105" />
onkeydown事件控制起来相对比较麻烦,上面的简化版很多键都没有涉及到,操作体验比较糟糕。 jQuery的两个插件使用起来还是比较灵活的,能够满足大部分需要,但是在控制输入长度上限制的很不灵活(或许是我没有发现灵活的使用方式?) 具体实现方法 使用maskedInput里的一部分方法来提取光标位置
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;
- 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" />
- ?1 $(".digitsOnly").keydown(validateDigitsOnly);
- 复制代码
复制代码
结尾 这个方法虽然有些地方效率还不够高,而且某些键盘key的还未处理,也不排除某些情况下可能失效,但是对于大多数情况下使用已经足够了。 大家若有额外需要请自行修改,当然有更好的办法也请分享(*^__^*) over PS:01.18更新了一些keyCode的判断,以及错把110写成109≡(▔﹏▔)≡ 另外需要注意:对于使用右键菜单或者是菜单栏粘贴进来的需要额外处理; 还有一种极端的情况:在网页中选中文字并拖动到文本框内,或者是在文本框中选中文字并拖动,这都需要做额外处理 对于以上两种需要额外处理的情况,比较便捷的方法是加一个验证,比如jQuery.validate之类的表单验证,否则处理起来比较麻烦
|