js代码有一百多行。
先上效果图
html代码
日期: <input type="text" id="dateInputer" class="hhm-dateInputer" placeholder="请输入日期">
设置input元素类名为 hhm-dateInputer,通过这个类来绑定这个日期输入控件。
js代码
这里应用了jQuery的库, 主要用于选择元素和绑定事件。
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
因为有大量的获取和设置光标位置操作,用到了上一篇博客介绍的几个工具函数。
1 //获取光标位置 2 function getCursor(elem) { 3 //IE 9 ,10,其他浏览器 4 if (elem.selectionStart !== undefined) { 5 return elem.selectionStart; 6 } else { //IE 6,7,8 7 var range = document.selection.createRange(); 8 range.moveStart("character", -elem.value.length); 9 var len = range.text.length; 10 return len; 11 } 12 } 13 //设置光标位置 14 function setCursor(elem, index) { 15 //IE 9 ,10,其他浏览器 16 if (elem.selectionStart !== undefined) { 17 elem.selectionStart = index; 18 elem.selectionEnd = index; 19 } else { //IE 6,7,8 20 var range = elem.createTextRange(); 21 range.moveStart("character", -elem.value.length); //左边界移动到起点 22 range.move("character", index); //光标放到index位置 23 range.select(); 24 } 25 } 26 //获取选中文字 27 function getSelection(elem) { 28 //IE 9 ,10,其他浏览器 29 if (elem.selectionStart !== undefined) { 30 return elem.value.substring(elem.selectionStart, elem.selectionEnd); 31 } else { //IE 6,7,8 32 var range = document.selection.createRange(); 33 return range.text; 34 } 35 } 36 //设置选中范围 37 function setSelection(elem, leftIndex, rightIndex) { 38 if (elem.selectionStart !== undefined) { //IE 9 ,10,其他浏览器 39 elem.selectionStart = leftIndex; 40 elem.selectionEnd = rightIndex; 41 } else { //IE 6,7,8 42 var range = elem.createTextRange(); 43 range.move("character", -elem.value.length); //光标移到0位置。 44 //这里一定是先moveEnd再moveStart 45 //因为如果设置了左边界大于了右边界,那么浏览器会自动让右边界等于左边界。 46 range.moveEnd("character", rightIndex); 47 range.moveStart("character", leftIndex); 48 range.select(); 49 } 50 }
------------------------- Boom! -----------------------
先讲讲主要的思路。 其实是可以画个图这里的,不过我都不晓得该怎么画,大家提提意见。
首先找到类名为 hhm-dateInputer的元素。
给它绑定两个事件处理函数。 keydown、focus
focus
判断如果input元素内容为空,那么设置其初始值为"____-__-__"
keydown
为什么不是keyup,而是keydown: 我们知道,keydown事件发生时,键盘上的字符还没有输入到输入框中,这很重要。如果需要,我们在程序中就可以阻止不合适的字符输入。
1.首先从事件对象event中取得keyCode值,判断为数字时,将数字后面的下划线删除一位。
2.keyCode值代表删除键时,删除数字,添加一位下划线。
3.keyCode的其他情况返回false,阻止字符的输入。
上面一二步会用到setTimeout函数,在其中执行某些操作。 使用这个函数是因为keyup事件中按键字符实际还没有作用到文本框中,setTimeout中的操作可以解决这个问题。
另外代码中还有一个很重要的方法 resetCursor,程序中多次调用这个方法来把光标设置到合适的输入位置。
//设置光标到正确的位置 function resetCursor(elem) { var value = elem.value; var index = value.length; //当用户通过选中部分文字并删除时,此时只能将内容置为初始格式洛。 if (elem.value.length !== dateStr.length) { elem.value = dateStr; } //把光标放到第一个_下划线的前面 //没找到下划线就放到末尾 var temp = value.search(/_/); index = temp > -1 ? temp : index; setCursor(elem, index); }
完整的js代码贴在下面咯。
1 $(function() { 2 var inputs = $(".hhm-dateInputer"); 3 var dateStr = "____-__-__"; 4 inputs.each(function(index, elem) { 5 var input = $(this); 6 input.on("keydown", function(event) { 7 // window.event1 = event; 8 var that = this; //当前触发事件的输入框。 9 var key = event.keyCode; 10 var cursorIndex = getCursor(that); 11 12 //输入数字 13 if (key >= 48 && key <= 57) { 14 //光标在日期末尾或光标的下一个字符是"-",返回false,阻止字符显示。 15 if (cursorIndex == dateStr.length || that.value.charAt(cursorIndex) === "-") { 16 return false; 17 } 18 //字符串中无下划线时,返回false 19 if (that.value.search(/_/) === -1) { 20 return false; 21 } 22 23 var fron = that.value.substring(0, cursorIndex); //光标之前的文本 24 var reg = /(\d)_/; 25 setTimeout(function() { //setTimeout后字符已经输入到文本中 26 //光标之后的文本 27 var end = that.value.substring(cursorIndex, that.value.length); 28 //去掉新插入数字后面的下划线_ 29 that.value = fron + end.replace(reg, "$1"); 30 //寻找合适的位置插入光标。 31 resetCursor(that); 32 }, 1); 33 return true; 34 //输入"Backspace" 删除键 35 } else if (key == 8) { 36 37 //光标在最前面时不能删除。 但是考虑全部文本被选中下的删除情况 38 if (!cursorIndex && !getSelection(that).length) { 39 return false; 40 } 41 //删除时遇到中划线的处理 42 if (that.value.charAt(cursorIndex - 1) == "-") { 43 var ar = that.value.split(""); 44 ar.splice(cursorIndex - 2, 1, "_"); 45 that.value = ar.join(""); 46 resetCursor(that); 47 return false; 48 } 49 setTimeout(function() { 50 //值为空时重置 51 if (that.value === "") { 52 that.value = "____-__-__"; 53 resetCursor(that); 54 } 55 //删除的位置加上下划线 56 var cursor = getCursor(that); 57 var ar = that.value.split(""); 58 ar.splice(cursor, 0, "_"); 59 that.value = ar.join(""); 60 resetCursor(that); 61 }, 1); 62 63 return true; 64 } 65 return false; 66 67 }); 68 input.on("focus", function(event) { 69 if (!this.value) { 70 this.value = "____-__-__"; 71 } 72 resetCursor(this); 73 }); 74 }); 75 //设置光标到正确的位置 76 function resetCursor(elem) { 77 var value = elem.value; 78 var index = value.length; 79 //当用户通过选中部分文字并删除时,此时只能将内容置为初始格式洛。 80 81 if (elem.value.length !== dateStr.length) { 82 elem.value = dateStr; 83 } 84 var temp = value.search(/_/); 85 index = temp > -1 ? temp : index; 86 setCursor(elem, index); 87 //把光标放到第一个_下划线的前面 88 //没找到下划线就放到末尾 89 } 90 }); 91 92 function getCursor(elem) { 93 //IE 9 ,10,其他浏览器 94 if (elem.selectionStart !== undefined) { 95 return elem.selectionStart; 96 } else { //IE 6,7,8 97 var range = document.selection.createRange(); 98 range.moveStart("character", -elem.value.length); 99 var len = range.text.length; 100 return len; 101 } 102 } 103 104 function setCursor(elem, index) { 105 //IE 9 ,10,其他浏览器 106 if (elem.selectionStart !== undefined) { 107 elem.selectionStart = index; 108 elem.selectionEnd = index; 109 } else { //IE 6,7,8 110 var range = elem.createTextRange(); 111 range.moveStart("character", -elem.value.length); //左边界移动到起点 112 range.move("character", index); //光标放到index位置 113 range.select(); 114 } 115 } 116 117 function getSelection(elem) { 118 //IE 9 ,10,其他浏览器 119 if (elem.selectionStart !== undefined) { 120 return elem.value.substring(elem.selectionStart, elem.selectionEnd); 121 } else { //IE 6,7,8 122 var range = document.selection.createRange(); 123 return range.text; 124 } 125 } 126 127 function setSelection(elem, leftIndex, rightIndex) { 128 if (elem.selectionStart !== undefined) { //IE 9 ,10,其他浏览器 129 elem.selectionStart = leftIndex; 130 elem.selectionEnd = rightIndex; 131 } else { //IE 6,7,8 132 var range = elem.createTextRange(); 133 range.move("character", -elem.value.length); //光标移到0位置。 134 //这里一定是先moveEnd再moveStart 135 //因为如果设置了左边界大于了右边界,那么浏览器会自动让右边界等于左边界。 136 range.moveEnd("character", rightIndex); 137 range.moveStart("character", leftIndex); 138 range.select(); 139 } 140 }
结束语
这个插件可能还有一些需要完善的地方。
缺少通过js调用为元素绑定此插件的接口
插件可能有些bug
上面的代码如果有任何问题,请大家不吝赐教。