经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » JavaScript » 查看文章
原生js日历选择器,学习js面向对象开发日历插件
来源:cnblogs  作者:蒋伟平  时间:2021/3/8 11:51:05  对本文有异议

在web开发过程中经常会碰到需要选择日期的功能,一般的操作都是在文本框点击,然后弹出日历选择框,直接选择日期就可以在文本框显示选择的日期。开发好之后给用户使用是很方便,但如果每一个日历选择器都要临时开发的话,会严重影响项目进度。所以网上有很多日历插件提供下载使用。

在实际工作中,日历选择器功能确实都是直接使用已开发好的插件。但作为一个前端工程师,还是需要知道具体实例方法,也应该有能力完成此类功能。本实例教程详细讲解怎么样使用原生js,通过面向对象来开发一个日历选择器插件。

一般日历插件使用都非常简单,只需要提供一个input元素就行,其他的工作都是通过插件来完成。本实例也先准备一个input元素待用,如下所示:

  1. <div style="text-align:center;">
  2. <input type="text" id="calendarInput">
  3. </div>
通过插件生成的日历弹框如图所示:

 

 

 

 在这里附上css样式,读者也可以根据喜好自己编写样式。css代码如下所示:

  1. *{box-sizing:border-box;}
  2. .calendar_wrap{position:relative;display:inline-block;margin:100px auto;}
  3. .calendar_wrap a{color:#333;text-decoration:none;cursor:pointer;}
  4. .calendar_container input{
  5. width:100%;border:1px solid #ccc;border-radius:4px;line-height:30px;
  6. font-size:14px;color:#333;outline:none;padding-left:6px;
  7. }
  8. .calendar_container .calendar_clean{position:absolute;top:6px;right:6px;z-index:1;display:none;cursor:pointer;}
  9. .calendar_container .calendar_clean:after{content:"\E62F";font-family:"iconfont";font-size:16px;display:inline-block;color:#ccc;}
  10. .calendar_container .calendar_icon{position:absolute;top:6px;right:6px;pointer-events:none;display:block;}
  11. .calendar_container .calendar_icon::after{content:"\E646";font-family:"iconfont";font-size:16px;display:inline-block;color:#aaa;}
  12. .calendar_container:hover .calendar_clean{display:block;}
  13. .calendar_container:hover .calendar_icon{display:none;}
  14. .calendar_main{
  15. position:absolute;top:36px;left:0px;width:220px;box-shadow:0px 0px 3px #ccc;
  16. border-radius:4px;z-index:2;background:#fff;
  17. }
  18. .calendar_main .calendar_head{font-size:0;}
  19. .calendar_main .calendar_head a{
  20. display:inline-block;height:32px;line-height:32px;
  21. text-align:center;font-size:12px;vertical-align:middle;
  22. }
  23. .calendar_main .calendar_head .chang_btn{width:30px;padding-top:1px;}
  24. .calendar_main .calendar_head .year_month_btn{width:64px;margin:0 48px;white-space:nowrap;}
  25. .calendar_main .calendar_head .year_btn,.calendar_main .calendar_head .month_btn{width:50px;}
  26. .calendar_main .calendar_head .chang_btn::after{content:"";display:inline-block;height:0;width:0;border:6px solid transparent;}
  27. .calendar_main .calendar_head .chang_btn::before{content:"";display:inline-block;height:0;width:0;border:6px solid transparent;}
  28. .calendar_main .calendar_head .left_year_btn::after{border-right-color:#aaa;margin-left:-14px;}
  29. .calendar_main .calendar_head .left_year_btn:hover::after{border-right-color:#f60;}
  30. .calendar_main .calendar_head .right_year_btn::after{border-left-color:#aaa;margin-left:-14px;}
  31. .calendar_main .calendar_head .right_year_btn:hover::after{border-left-color:#f60;}
  32. .calendar_main .calendar_head .left_month_btn::after{border-right-color:#fff;margin-left:-10px;}
  33. .calendar_main .calendar_head .left_month_btn::before{border-right-color:#aaa;}
  34. .calendar_main .calendar_head .left_month_btn:hover::before{border-right-color:#f60;}
  35. .calendar_main .calendar_head .right_month_btn::after{border-left-color:#fff;margin-left:-14px;}
  36. .calendar_main .calendar_head .right_month_btn::before{border-left-color:#aaa;}
  37. .calendar_main .calendar_head .right_month_btn:hover::before{border-left-color:#f60;}
  38. .calendar_main .calendar_head a:hover{color:#f60;}
  39. .calendar_main .calendar_body{border-top:1px solid #ccc;border-bottom:1px solid #ccc;}
  40. .calendar_main .calendar_body table{width:100%;table-layout:fixed;}
  41. .calendar_main .calendar_body th{text-align:center;line-height:20px;font-size:12px;}
  42. .calendar_main .calendar_body td{padding:0 4px;height:24px;text-align:center;font-size:12px;}
  43. .calendar_main .calendar_body td a{display:inline-block;width:20px;height:20px;cursor:pointer;line-height:20px;color:#ccc;}
  44. .calendar_main .calendar_body .cur_month{color:#666;background:inherit;}
  45. .calendar_main .calendar_body .cur_day{
  46. border-radius:2px;font-weight:bold;line-height:18px;background:#eee;color:#000
  47. }
  48. .calendar_main .calendar_body .sel_day{color:#fff;background:#f60;border-radius:2px;}
  49. .calendar_main .calendar_foot{padding:6px 10px;text-align:right;}
  50. .calendar_main .calendar_foot .define_btn{
  51. border-radius:4px;line-height:24px;height:24px;border:0;
  52. background:none;color:#666;cursor:pointer;outline:none;
  53. }
  54. .calendar_main .calendar_foot .define_btn:hover{color:#f60;}
  55. .calendar_main .calendar_body ul{font-size:0;margin:0;padding:0;}
  56. .calendar_main .calendar_body li{display:inline-block;width:55px;height:60px;line-height:54px;font-size:14px;}
  57. .calendar_main .calendar_body li a{padding:8px;}
  58. .calendar_main .calendar_body li .no_cur{color:#ccc;}

 接下来开始封装日历选择器插件。新建 calendar.js 文件,接下来的插件代码都写在此文件中。

需要在body元素中引入 calendar.js 文件,如下所示:

  1. <script src="js/calendar.js"></ script>

 

把日历选择器功能拆分成一个一个的步骤来完成。

1. 声明一个日历选择器插件的构造函数,可以传入input元素和配置选项两个参数,如下所示:
  1. //创建日历插件构造函数
  2. function CalendarPlugin(elem,opt={}){
  3. }
创建好这个函数之后,先在html文件中调用,这样可以在开发的过程中随时查看效果,如下所示:
  1. <script src="js/calendar.js"></script>
  2. <script>
  3. //获取文本框
  4. var eCalendarInput = document.getElementById('calendarInput');
  5. //配置选项
  6. var oConfig = {
  7. }
  8. //调用日历构造函数生成实例对象
  9. var oCalenderObj = new CalendarPlugin(eCalendarInput,oConfig);
  10. </script>

 

2. 在构造函数的原型对象上创建init方法,并在构造函数中调用,如下所示:
  1. //创建日历插件构造函数
  2. function CalendarPlugin(elem,opt={}){
  3. //执行初始化
  4. this.init();
  5. }
  6. //初始化
  7. CalendarPlugin.prototype.init = function(){
  8. }

 

3. 创建日历插件所需要有元素
日历插件包括的元素比较多,开发过程中不要急,按照步骤,从上至下一个一个生成元素。
3.1 创建包裹和input容器等元素,把原文本框移到包裹元素中,并将包裹放到原父元素中,如下所示: 
  1. //创建日历插件构造函数
  2. function CalendarPlugin(elem,opt={}){
  3. //把文本框设置为日历对象的属性
  4. this.eInput = elem;
  5. /*...*/
  6. }
  7. //初始化
  8. CalendarPlugin.prototype.init = function(){
  9. //获取原有intpu元素的父元素
  10. var eInputParent = this.eInput.parentNode;
  11. //创建日历包裹元素并添加class名称
  12. var eWrap = document.createElement('div');
  13. eWrap.className = 'calendar_wrap';
  14. //创建文本框容器元素
  15. var eInputContainer = document.createElement('div');
  16. eInputContainer.className = 'calendar_container';
  17. //创建清除按钮
  18. var eClear = document.createElement('div');
  19. eClear.className = 'calendar_clean';
  20. //创建日历图标元素
  21. var eIcon = document.createElement('div');
  22. eIcon.className = 'calendar_icon';
  23. //把日历包裹放到原有父元素中
  24. eInputParent.appendChild(eWrap);
  25. //文本框容器放到包裹中
  26. eWrap.appendChild(eInputContainer);
  27. //把相关元素放到文本框容器中
  28. eInputContainer.appendChild(this.eInput);
  29. eInputContainer.appendChild(eClear);
  30. eInputContainer.appendChild(eIcon);
  31. //设置文本框为只读
  32. this.eInput.setAttribute('readonly',true);
  33. }

此时文档框已经变成日历选择器的样式了,如图所示:

 

3.2 在init方法中创建弹出日历选择框元素

  1. CalendarPlugin.prototype.init = function(){
  2. /*...*/
  3.  
  4. //创建主要日历容器元素
  5. this.eMain = document.createElement('div');
  6. this.eMain.className = 'calendar_main';
  7. //把日历容器放到包裹元素中
  8. eWrap.appendChild(this.eMain);
  9. }

 

3.3 在日历选择框中添加头部元素、主体元素和底部元素,代码如下:

  1. CalendarPlugin.prototype.init = function(){
  2. /*...*/
  3.  
  4. //创建日历头部
  5. this.eHead = document.createElement('div');
  6. this.eHead.className = 'calendar_head';
  7. //把日历头部放到日历容器中
  8. this.eMain.appendChild(this.eHead);
  9. //设置当前年份
  10. this.nYear = null;
  11. //设置当前月份
  12. this.nMonth = null;
  13. //设置日历模式,默认显示日历
  14. this.sModel = 'date';
  15. //创建日历主体
  16. this.eBody = document.createElement('div');
  17. this.eBody.className = 'calendar_body';
  18. //把日历主体放到日历容器中
  19. this.eMain.appendChild(this.eBody);
  20. //当前选定日期
  21. this.selDate = null;
  22. //创建底部元素
  23. this.eFoot = document.createElement('div');
  24. this.eFoot.className = 'calendar_foot';
  25. this.eDefine = document.createElement('button');
  26. this.eDefine.className = 'define_btn';
  27. //把底部元素放到日历容器中
  28. this.eMain.appendChild(this.eFoot);
  29. this.eFoot.appendChild(this.eDefine);
  30. this.eDefine.innerHTML = '今 天';
  31. }

此时效果如图所示:

 

 

 只有底部有一个“今 天”的按钮,头部年/月和主要的日期都还没有,接下来开始创建这些元素

 

3.4 创建日历选择框中的头部和日期元素

  1. //初始化
  2. CalendarPlugin.prototype.init = function(){
  3. /*...*/
  4.  
  5. //生成日历元素
  6. this.generateDate();
  7. }
  8. //创建头部元素
  9. CalendarPlugin.prototype.generateHead = function(){
  10. //根据日历模式不同,组成日历头部html代码
  11. var sHeadHtml = '<a class="left_year_btn chang_btn" data-run="lessYear"></a>';
  12. if(this.sModel == 'date'){ //日历模式
  13. sHeadHtml += `<a class="left_month_btn chang_btn" data-run="lessMonth"></a>
  14. <a class="year_btn" data-run="showYear" data-model="year">${this.nYear}年</a>
  15. <a class="month_btn" data-run="showMonth" data-model="month">${+this.nMonth+1}月</a>
  16. <a class="right_month_btn chang_btn" data-run="addMonth"></a>`;
  17. }else if(this.sModel == 'month'){ //月历模式
  18. sHeadHtml += `<a class="year_month_btn" data-run="showYear" data-model="year">${this.nYear}年</a>`;
  19. }else if (this.sModel == 'year'){ //年历模式
  20. sHeadHtml += `<a class="year_month_btn">${+(Math.floor(this.nYear/10)+'0')}-
  21. ${+(Math.floor(this.nYear/10)+'0')+10}</a>`;
  22. }
  23. sHeadHtml += '<a class="right_year_btn chang_btn" data-run="addYear"></a>';
  24. //填充日历头部
  25. this.eHead.innerHTML = sHeadHtml;
  26. }
  27. //生成日历
  28. CalendarPlugin.prototype.generateDate = function(date=null){
  29. //组成日历的html代码
  30. var sBodyHtml = '<table>';
  31. //组合周日 - 周六的列表头
  32. sBodyHtml += `<thead>
  33. <tr><th>日</th><th>一</th><th>二</th><th>三</th><th>四</th><th>五</th><th>六</th></tr>
  34. </thead>`
  35.  
  36. /*日历中需要记录当前日期、选定日期、面板日期共三个时间*/
  37. //当前日期:当前日期在日历面板中有一个背景和加粗字体,需要添加class为cur_day
  38. var dCurDate = new Date();
  39. //选定日期:在面板上选择的日期,并且显示在文本框中,有一个背景和白色字体,需要添加class为sel_day
  40. //选定日期需要记录在日历实例的selDate属性上,如果暂无选定日期则为当前日期
  41. var dSelDate = this.selDate || dCurDate;
  42. //初始化当前年/月
  43. this.nYear = this.nYear || dSelDate.getFullYear();
  44. this.nMonth = this.nMonth || dSelDate.getMonth();
  45. //面板上显示的日历
  46. var dShowDate = new Date(this.nYear,this.nMonth,dSelDate.getDate());
  47. /*
  48. 日历面板规则:
  49. 显示42天,6行7列;
  50. 面板上的第一天是当月1号往前推到星期日。比如当月1号是星期一则上月显示1天、星期三上月显示3天、星期日上月显示7天;
  51. */
  52. //计算上月要显示的天数
  53. var nFrontNum = new Date(this.nYear,this.nMonth,1).getDay() || 7;
  54. //日历面板上的日期每增加一个循环周期是一天,获取一天的毫秒数
  55. var cycle = 1000*60*60*24;
  56. sBodyHtml += '<thbody>'
  57. //循环42次
  58. for(let i=1;i<43;i++){
  59. //以下公式获取日历中每天递增日期的时间戳
  60. let dTimes = +dShowDate + cycle * (i-nFrontNum-dShowDate.getDate());
  61. //通过时间戳创建Date实例对象
  62. let dNewDate = new Date(dTimes);
  63. //获取日期添加到html中
  64. if((i-1)%7==0){ //判断是否需要换行
  65. sBodyHtml += '<tr>';
  66. }
  67. //判断是否是选定日期,当前日期,面板当月日期,分别加上对应的class
  68. sBodyHtml += `<td><a data-time="${dTimes}" class="${
  69. this.quiteDate(dNewDate,dSelDate)?'sel_day':
  70. this.quiteDate(dNewDate,dCurDate)?'cur_day':
  71. dNewDate.getMonth()==this.nMonth?'cur_month':''
  72. }">${dNewDate.getDate()}</a></td>`;
  73. if(i%7==0){ //判断是否需要结束表格行
  74. sBodyHtml += '</tr>';
  75. }
  76. }
  77. sBodyHtml += '</thbody></table>';
  78. //填充日历面板
  79. this.eBody.innerHTML = sBodyHtml;
  80. //生成面板头部
  81. this.generateHead();
  82. }
  83. //比较两个日期是否为同一天
  84. CalendarPlugin.prototype.quiteDate = function(d1,d2){
  85. var format = 'yyyy-MM-dd';
  86. return this.format(d1,format) == this.format(d2,format);
  87. }
  88. //格式化日期
  89. CalendarPlugin.prototype.format = function(date,format){
  90. //用于正则表达式的匹配
  91. var o = {
  92. "M+" : date.getMonth()+1, //
  93. "d+" : date.getDate(), //
  94. "h+" : date.getHours(), //小时
  95. "m+" : date.getMinutes(), //分钟
  96. "s+" : date.getSeconds(), //
  97. };
  98. //使用正则将yyyy替换为当前年份
  99. if(/(y+)/.test(format)){
  100. format = format.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
  101. }
  102. //枚举o对象中匹配的正则,比如MM替换当前月份,dd替换为当前日期
  103. for(var k in o) {
  104. if(new RegExp("("+ k +")").test(format)){
  105. format = format.replace(RegExp.$1, RegExp.$1.length==1 ? o[k] : ("00"+ o[k]).substr((""+ o[k]).length));
  106. }
  107. }
  108. //把格式替换为正确日期后返回
  109. return format;
  110. }

此时效果如图所示:

 

 

 到这一步,日历选择器的元素大部分都已经创建。这段代码新加了几个方法,分别用于创建头部、日期等,因为我都写了详细的注释,这里就不再赘述。接下来需要给元素绑定事件,实现日期变化和选择等。

 

4. 添加配置选项

插件一般都会允许开发人员根据项目需求做个性化设置,所以可以自行修改配置,比如设置初始日期、文本框提示、日期格式等。比如在输入框添加提示,可以修改配置选项代码如下:

  1. //获取文本框
  2. /*...*/
  3.  
  4. //配置选项
  5. var oConfig = {
  6. placeholder:'请选择日期',
  7. }
  8. //调用日历构造函数生成实例对象
  9. /*...*/

修改构建函数,在里面添加默认配置选项代码,如下所示:

  1. //创建日历插件构造函数
  2. function CalendarPlugin(elem,opt={}){
  3. //把文本框设置为日历对象的属性
  4. /*...*/
  5.  
  6. //默认配置选项
  7. this.oConfig = {
  8. format:'yyyy-MM-dd', //日期格式
  9. value:null, //默认日期
  10. placeholder:'' //文本框提示
  11. }
  12. //修改为传入的配置选项
  13. for(let k in this.oConfig){
  14. opt[k] && (this.oConfig[k] = opt[k]);
  15. }
  16. //执行初始化
  17. /*...*/
  18. }

在初始化方法中设置相关配置

  1. //初始化
  2. CalendarPlugin.prototype.init = function(){
  3. /*...*/
  4.  
  5. //默认赋值
  6. this.oConfig.value && (this.eInput.value = this.oConfig.value) && (this.selDate = new Date(this.oConfig.value));
  7. //设置文本框提示
  8. this.eInput.placeholder = this.oConfig.placeholder;
  9. }

此时可以看到输入框中就有了默认提示信息,如图所示:

 

 

 

5. 添加绑定事件

5.1 输入框绑定点击事件,点击显示日历面板

默认情况下,应该先把日历面板设置隐藏

  1. CalendarPlugin.prototype.init = function(){
  2. /*...*/
  3.  
  4. //默认隐藏日历面板
  5. this.eMain.style.display = 'none';
  6. }

再给输入框添加事件,生成并显示日历。this.generateDate() 方法也应该放到事件中再调用,代码中有详细注释:

  1. //初始化
  2. CalendarPlugin.prototype.init = function(){
  3. /*...*/
  4.  
  5. //文本框点击显示日历面板
  6. this.eInput.addEventListener('click',()=>{
  7. if(this.eMain.style.display=='none'){
  8. //显示日历面板
  9. this.eMain.style.display = 'block';
  10. //在页面上绑定点击事件,除日历面板以外任何位置点击鼠标时,隐藏日历面板
  11. document.addEventListener('click',hideMain,false);
  12. //默认显示日历
  13. this.sModel = 'date';
  14. //初始化年/月
  15. this.nYear = null;
  16. this.nMonth = null;
  17. //生成日历
  18. this.generateDate();
  19. }else{
  20. //隐藏日历面板
  21. hideMain();
  22. }
  23. });
  24. //因为addEventListener监听事件必须是命名函数才能取消,所以在这里创建一个隐藏日历面板函数
  25. var eMain = this.eMain;
  26. function hideMain(){
  27. eMain.style.display = 'none';
  28. document.removeEventListener('click',hideMain,false);
  29. }
  30. //阻止冒泡
  31. eWrap.addEventListener('click',function(event){
  32. event.stopPropagation();
  33. });
  34. }

此时已经实现输入框点击显示日历选择框,空白位置点击隐藏日历选择框功能。

 

5.2 日期面板绑定点击事件,选择日期或今天按钮,修改文本框的值,并且隐藏日历面板

  1. //初始化
  2. CalendarPlugin.prototype.init = function(){
  3. /*...*/
  4.  
  5. //日期面板点击事件
  6. this.eBody.addEventListener('click',(event)=>{
  7. //获取点击的元素
  8. let eTarget = event.target;
  9. //获取日期时间戳
  10. let sTime = eTarget.dataset.time;
  11. //获取月
  12. let sMonth = eTarget.dataset.month;
  13. //获取年
  14. let sYear = eTarget.dataset.year;
  15. //获取当前元素className
  16. let sClass = eTarget.className;
  17. if(this.sModel=='date'){ //当前模式是日期,在输入框显示日期,并隐藏日历面板
  18. if(sTime && sClass != 'sel_day'){
  19. this.selDate = new Date(+sTime);
  20. this.eInput.value = this.format(this.selDate,this.oConfig.format);
  21. hideMain();
  22. }
  23. }else{
  24. if(sMonth||sYear){ //年历或月历面板,创建选择的年或月的日期
  25. this.nYear = sYear || this.nYear;
  26. this.nMonth = sMonth || this.nMonth;
  27. this.sModel = 'date';
  28. this.generateDate();
  29. }
  30. }
  31. });
  32. //点击今天按钮选择今天的日期
  33. this.eDefine.addEventListener('click',(event)=>{
  34. this.selDate = new Date();
  35. this.eInput.value = this.format(this.selDate,this.oConfig.format);
  36. hideMain();
  37. });
  38. }

此时选择日期后效果如下所示:

 

 

5.3 头部元素绑定点击事件,实例修改年、月,选择年、月等功能,代码如下:

  1. //初始化
  2. CalendarPlugin.prototype.init = function(){
  3. /*...*/
  4.  
  5. //日历面板头部点击事件
  6. this.eHead.addEventListener('click',(event)=>{
  7. //获取点击的元素
  8. let eTarget = event.target;
  9. //获取修改方式
  10. let sRun = eTarget.dataset.run;
  11. //获取面板模式
  12. let sModel = eTarget.dataset.model;
  13. this.sModel = sModel || this.sModel;
  14. if(sRun=='addYear'){ //切换后一年
  15. if(this.sModel=='year'){
  16. this.nYear+=10;
  17. }else{
  18. this.nYear++;
  19. }
  20. }else if(sRun=='lessYear'){ //切换前一年
  21. if(this.sModel=='year'){
  22. this.nYear-=10;
  23. }else{
  24. this.nYear--;
  25. }
  26. }else if(sRun=='addMonth'){ //切换下一个月
  27. this.nMonth++;
  28. }else if(sRun=='lessMonth'){ //切换前一个月
  29. this.nMonth--;
  30. }
  31. if(this.sModel=='year'){
  32. this.generateYear();
  33. }else if(this.sModel=='month'){
  34. this.generateMonth();
  35. }else{
  36. this.generateDate(new Date(this.nYear,this.nMonth,1)); //因为切换只年月没选择日期,日期可以任意一天,所以设置为1号
  37. }
  38. });
  39. }
  40. /*...*/
  41.  
  42. //生成月历
  43. CalendarPlugin.prototype.generateMonth = function(){
  44. //生成月份的html元素
  45. let sBodyHtml = '<ul>';
  46. for(let i=0;i<12;i++){
  47. sBodyHtml += `<li><a data-month="${i+1}" class="${i==this.nMonth?'sel_day':''}">${i+1}月</a></li>`
  48. }
  49. sBodyHtml += '</ul>';
  50. this.eBody.innerHTML = sBodyHtml;
  51. //生成面板头部
  52. this.generateHead();
  53. }
  54. //生成年历
  55. CalendarPlugin.prototype.generateYear = function(){
  56. //共显示12年,可以通过把当前年最后一个数字改为0获取10年中的第一年
  57. let nStart = +(Math.floor(this.nYear/10)+'0');
  58. //再从-1开始循环到11,就可以循环出12年
  59. //生成年份的html元素
  60. let sBodyHtml = '<ul>';
  61. for(let i=-1;i<11;i++){
  62. sBodyHtml += `<li><a data-year="${i+nStart}" class="${
  63. i==-1||i==10?'no_cur':
  64. i+nStart==this.nYear?'sel_day':''
  65. }">${i+nStart}</a></li>`
  66. }
  67. sBodyHtml += '</ul>';
  68. //修改面板
  69. this.eBody.innerHTML = sBodyHtml;
  70. //生成面板头部
  71. this.generateHead();
  72. }

日期选择器功能已经基本完成,这已经是一个可以在项目中正常使用的日期选择器,如有疑问或bug,欢迎在留言中提出,感谢!

原文链接:http://www.cnblogs.com/jiangweiping/p/14471642.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号