一个简单的日期输入格式化控件。

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

上面的代码如果有任何问题,请大家不吝赐教。

时间: 2024-11-09 00:06:11

一个简单的日期输入格式化控件。的相关文章

类实现一个简单的日期计算器

作为一个程序员,对于时间的概念已经退化到了三岁小孩水平,常常会醉心于写一个程序忘记了时间,一个下午,一天,甚至一个星期就过去了.对于一个刚入程序员大门的我来说,时光真的是匆匆溜走,所以经常会百度一个日期计数器,算今天到那些特别的日子还有多少天.用多了后就觉得现在储备的编程知识可以去实现一个简单的日期计算器了.所以就写了这篇博客给大家分享一下. 首先,得设计这个日期类,一个日期类应该具有私有数据成员应该有年Year,月month,日day.在这我们就不精确到时分秒了. #pragma once #

实现一个简单的marked编辑格式转换器部分功能

首先需要在项目里安装marked格式编辑包 在项目根目录下运行npm install marked 安装依赖包 至此,package.json里面 dependencies 已经添加     "marked": "^0.5.1", 然后在需要显示的组件里编写显示区域: 1 <div class="mark"> 2 <textarea rows="10" cols="100" class=&

AngularJS 创建一个简单可交互的控件(一)

这几天开始学习Angular这个MVC框架, 边看官网文档和youtube视频边做实例, 现在整理下自己的学习所得与大家分享, 也希望有Angular的大牛们来指教和探讨. 我们设想一个最基本的Web应用场景: 从服务器获取数据,通过这些数据来动态渲染我们的页面. 假设我们目前需要获取一组团队所有成员的信息并且显示, 团队成员的信息有成员名字, 年龄. (示例的控件在页面上的截图) 首先我们需要为我们所需要渲染的页面写一个简单的模板: 创建这个控件的时候我使用的是flatui所设计的扩展boot

AcWing:242. 一个简单的整数问题(树状数组)

给定长度为N的数列A,然后输入M行操作指令. 第一类指令形如“C l r d”,表示把数列中第l~r个数都加d. 第二类指令形如“Q X”,表示询问数列中第x个数的值. 对于每个询问,输出一个整数表示答案. 输入格式 第一行包含两个整数N和M. 第二行包含N个整数A[i]. 接下来M行表示M条指令,每条指令的格式如题目描述所示. 输出格式 对于每个询问,输出一个整数表示答案. 每个答案占一行. 数据范围 1≤N,M≤1051≤N,M≤105,|d|≤10000|d|≤10000,|A[i]|≤1

acwing 243. 一个简单的整数问题2 树状数组 线段树

地址 https://www.acwing.com/problem/content/description/244/ 给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一: 1.“C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d. 2.“Q l r”,表示询问 数列中第 l~r 个数的和. 对于每个询问,输出一个整数表示答案. 输入格式 第一行两个整数N,M. 第二行N个整数A[i]. 接下来M行表示M条指令,每条指令的格式如题目描述所示. 输出格式 对于

c#代码01--控制台的简单输入与输出及日期的格式输出

/* 使用ReadLine()完成控制台的输入输出内容 */ using System; namespace Test { class Test1 { static void Main(string[] args){ Console.Write("请输入:");//输出 请输入 且不换行 string read = Console.ReadLine();//将输入内容赋值到变量read Console.Write("您输入的内容为:");//控制台输出 您输入的内容

用MFC完成一个简单的猜数字游戏: 输入的四位数中,位置和数字都正确为A,数字相同而位置不同的为B。

最近学习了MFC一些比较基础的知识,所以打算通过做一个简单的数字游戏来理解MFC的流程并进一步熟悉其操作. 在这里,我做了一个猜数字的小游戏.第一步当然是设计主界面,先给大家展示一下游戏界面: 主界面: 从这个主界面可以看到,它包含标题,菜单栏,工具栏. 标题是给人一个认识,这是什么游戏,标题设置为:“猜数游戏”: 而菜单栏和工具栏才是游戏的核心,它要保证能够完成游戏的基本功能. 菜单栏和工具栏是对应的,包含了”start“,"help","restart"这三个菜

移动端日期、地址控件的简单使用

首先申明一点,这个插件不是我写的,是网上一个大神写的,这是他的博客大家可以参考一下:http://www.cnblogs.com/xiangbing/p/mobile-select-area.html ===========================================分割线========================= 在下呢只是就这个插件做了一下简单的适应性改进,需要的朋友可以往下看: 刚开始我也是在网上各种找插件,但是遇到一个问题就是项目要求样式统一,但是各种五花八门

【Visual Basic】纯代码不拖控件,利用动态生成控件的方式完成一个简单的四则运算计算器

vb6是一个典型的拖控件加代码的编程代表,因此也一直被认为难登大雅之堂,但是,在vb6中可以完全纯粹地使用代码控制这个窗体与窗体的控件.这样生成出来的控件位置摆放精确无比,无须拖好控件之后,再利用工具栏的"格式"菜单慢慢地调整大小.这种方式的确定是声明一个控件要耗费大量的代码,但其实Java中的Swing,HTML+CSS排放控件,比这好不了多少. 当然,比vc6中mfc的代码简单了不少,具体见<[mfc]基本对话框程序--加法器>(点击打开链接) 一.基本目标 利用纯粹代