flutter + 小程序 + 后端,3个人就可开启你的APP之路 | 双十一特惠-注册送大疆、华为、樱桃键盘!>>>
设计目标:不依赖其他库、兼容一些旧版浏览器、可配置可扩展。
测试页面:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>测试日历控件</title> 6 <style> 7 #div1{ 8 width: 256px; 9 height: 202px; 10 box-sizing: border-box; 11 background-color: #fff; 12 box-shadow: 1px 1px 3px #999; 13 position:absolute; 14 left:0px; 15 } 16 #div2 { 17 width: 236px; 18 height: 166px; 19 box-sizing: border-box; 20 background-color: #fff; 21 box-shadow: 1px 1px 3px #999; 22 position:absolute; 23 left:300px; 24 } 25 .select_date{ 26 padding-left: 10px;box-sizing:border-box;width: 100px;height: 30px;background-color: #fff;font-size: 12px;float: left;line-height: 30px; 27 } 28 .span_rq{ 29 width: 60px;display: inline-block; 30 } 31 </style> 32 <script src="DatePicker.js"></script> 33 </head> 34 <body> 35 <div id="div_all_base" style="background-color: beige"> 36 <div id="div1"> 37 38 </div> 39 <div id="div2"> 40 41 </div> 42 <div style="width: 600px;height: 30px;left:600px;position:absolute;float:left" id="div3"> 43 <div style="float: left;line-height: 30px;margin-left: 10px;font-size: 12px;">从</div> 44 <div class="select_date"><span class="span_rq">开始日期</span><img src="image/rili2.jpg" style="margin-left: 10px;width: 20px;margin-top: 6px;cursor: pointer" alt="" onclick="var divs=div_rilis.getElementsByClassName('div_rili');divs[0].style.display='block';divs[1].style.display='none'"></div> 45 <div style="position: absolute;width:256px;height: 202px;top:50px;display: none" class="div_rili"></div> 46 <div style="float: left;line-height: 30px;margin-left: 10px;font-size: 12px;">到</div> 47 <div class="select_date"><span class="span_rq">结束日期</span><img src="image/rili2.jpg" style="margin-left: 10px;width: 20px;margin-top: 6px;cursor: pointer" alt="" onclick="var divs=div_rilis.getElementsByClassName('div_rili');divs[1].style.display='block';divs[0].style.display='none'"></div> 48 <div style="position: absolute;width:256px;height: 202px;top:50px;left:120px;display: none" class="div_rili"></div> 49 </div> 50 </div> 51 </body> 52 <script> 53 var div_rilis=document.getElementById("div3"); 54 55 var apiHost=""; 56 var data_enabledate={list_enabledate:[{CBRQ:20201111},{CBRQ:20201112},{CBRQ:20201113},{CBRQ:20201114},{CBRQ:20201115}],type:"ok"}; 57 //用AJAX从后端查询可选日期,需要返回数据的格式与data_enabledate相同 58 //var datepicker1=new DatePicker("datepicker1",{pickcallback:loadPage,bannerBackColor:"rgb(0,112,192)",searchEnableUrl:apiHost+"/public/searchEnableDate"});// 59 //直接用前端数据,设置了点击回调、banner颜色、激活日期 60 var datepicker1=new DatePicker("datepicker1",{pickcallback:loadPage,bannerBackColor:"rgb(0,112,192)",searchEnableUrl:data_enabledate}); 61 var div_rili1=document.getElementById("div1"); 62 div_rili1.appendChild(datepicker1.div); 63 datepicker1.reloadDateList(); 64 65 //设置更多的配置项,被点击的按钮变色,程序可以在一定的范围内根据外围div的大小调整每个按钮的尺寸,另外设置了字体大小,以及允许点击未激活日期 66 var datepicker2=new DatePicker("datepicker2",{ 67 pickcallback:function(str_date,that){ 68 datepicker2.pick0(str_date); 69 loadPage(str_date); 70 },bannerBackColor:"rgb(0,112,192)",width:236,height:166,shadowSize:0,paddingSize:0, 71 searchEnableUrl:data_enabledate,contentFontSize:9,flag_canPickUnEnabled:true, 72 }); 73 var div_rili2=document.getElementById("div2"); 74 div_rili2.appendChild(datepicker2.div); 75 datepicker2.reloadDateList(); 76 77 function loadPage(str_date){ 78 79 alert("点击的日期是"+str_date); 80 } 81 82 //常用的起始日期和结束日期,这里设置了每个日历的title,不区分激活按钮,并且把日历的值与span的innerHTML关联起来(使用arr_valuelink属性可以关联input或textview的value) 83 var divs=div_rilis.getElementsByClassName('div_rili'); 84 var spans=div_rilis.getElementsByClassName("span_rq"); 85 var datepicker1b=new DatePicker("datepicker1b",{pickcallback:function(value,that){ 86 var divs=div_rilis.getElementsByClassName('div_rili'); 87 divs[0].style.display='none'; 88 divs[1].style.display='none'; 89 DatePicker.linkValue(value,that) 90 },bannerBackColor:"rgb(0,112,192)",arr_innerlink:[spans[0]],title:"开始日期"});//与react不同这里的spans在onload后不会再重新生成,所以可以直接关联dom对象!! 91 var datepicker2b=new DatePicker("datepicker2b",{pickcallback:function(value,that){ 92 var divs=div_rilis.getElementsByClassName('div_rili'); 93 divs[0].style.display='none'; 94 divs[1].style.display='none'; 95 DatePicker.linkValue(value,that) 96 },bannerBackColor:"rgb(0,112,192)",arr_innerlink:[spans[1]],title:"结束日期"}); 97 divs[0].appendChild(datepicker1b.div); 98 divs[1].appendChild(datepicker2b.div); 99 datepicker1b.reloadDateList();100 datepicker2b.reloadDateList();101 </script>102 </html>
日历按钮图片:
代码实现:(建议从后往前看)
1 DatePicker=function(id,obj_p) 2 { 3 //如果已经有这个div则建立失败 4 var div=document.getElementById("id"); 5 if(div) 6 { 7 console.log("组件id重复,请使用其他组件id"); 8 return; 9 } 10 div=document.createElement("div");//最外层容器 11 this.id=id; 12 this.div=div; 13 div.id=id; 14 var _this=this; 15 16 this.width=obj_p.width||256; 17 this.height=obj_p.height||202; 18 this.shadowSize=obj_p.shadowSize||4; 19 this.shadowColor=obj_p.shadowColor||"rgb(203,203,203)"; 20 this.backColor=obj_p.backColor||"white"; 21 //this.boxShadow=obj_p.boxShadow||"inset 0 0 4px 4px rgb(203,203,203)"; 22 div.style.border="0px"; 23 div.style.width=this.width+"px"; 24 div.style.height=this.height+"px"; 25 div.style.boxShadow="inset 0 0 "+this.shadowSize+"px "+this.shadowSize+"px "+this.shadowColor; 26 div.style.position="absolute"; 27 div.style.backgroundColor=this.backColor; 28 29 this.title=obj_p.title||"日期选择"; 30 //this.noTitle=obj.noTitle||false; 31 //this.noBanner=obj.noBanner||false; 32 this.h1=obj_p.h1||24;//最上面的一行空间 33 this.h2=obj_p.h2||24; 34 //this.h3=obj_p.h3||208; 35 this.titleFontSize=obj_p.titleFontSize||12; 36 this.contentFontSize=obj_p.contentFontSize||10; 37 var span=document.createElement("span")//日历的标题栏 38 span.innerText=this.title; 39 span.style.height=this.h1+"px"; 40 span.style.fontSize=this.titleFontSize+"px"; 41 span.style.fontWeight="bold"; 42 span.style.lineHeight=this.h1+"px"; 43 span.style.display="inline-block"; 44 span.style.left=this.shadowSize+"px"; 45 span.style.paddingLeft=this.shadowSize+"px"; 46 span.style.position="absolute"; 47 span.style.zIndex="2"; 48 div.appendChild(span); 49 50 this.bannerBackColor=obj_p.bannerBackColor||"rgb(169,16,10)"; 51 this.bannerFontColor=obj_p.bannerFontColor||"white"; 52 this.date=obj_p.date||(new Date());//默认日期 53 this.year=this.date.getFullYear(); 54 this.month=this.date.getMonth(); 55 this.day31=this.date.getDate(); 56 this.day7=this.date.getDay(); 57 this.arr_day7=obj_p.arr_day7||["","一","二","三","四","五","六","日"]; 58 this.arr_bannerp=obj_p.arr_bannerp||([//用来调整年月的按钮 59 {id:"btn1",width:10,marginLeft:20,text:"《",onclick:function(){_this.year-=10;_this.changeYear()}} 60 ,{id:"btn2",width:10,marginLeft:5,text:"〈",onclick:function(){_this.year-=1;_this.changeYear()}} 61 ,{id:"btn3",width:40,marginLeft:5,text:this.year,onclick:function(){}} 62 ,{id:"btn4",width:10,marginLeft:5,text:"〉",onclick:function(){_this.year+=1;_this.changeYear()}} 63 ,{id:"btn5",width:10,marginLeft:5,text:"》",onclick:function(){_this.year+=10;_this.changeYear()}} 64 ,{id:"btn6",width:10,marginLeft:50,text:"〈",onclick:function(){_this.month-=1;if(_this.month<0){_this.month=11;_this.year-=1;}_this.changeMonth();_this.changeYear()}} 65 ,{id:"btn7",width:20,marginLeft:5,text:this.month+1,onclick:function(){}} 66 ,{id:"btn8",width:10,marginLeft:5,text:"〉",onclick:function(){_this.month+=1;if(_this.month>11){_this.month=0;_this.year+=1;}_this.changeMonth();_this.changeYear()}} 67 ]) 68 69 var div_banner=document.createElement("div"); 70 div_banner.style.height=this.h2+"px"; 71 //div_banner.style.width="100%"; 72 div_banner.style.left=this.shadowSize+"px"; 73 div_banner.style.right=this.shadowSize+"px"; 74 div_banner.style.top=this.h1+"px"; 75 div_banner.style.position="absolute"; 76 div_banner.style.backgroundColor=this.bannerBackColor; 77 div_banner.style.lineHeight=this.h2+"px"; 78 div_banner.style.zIndex="2"; 79 //div_banner.style.fontSize=this.contentFontSize+2+"px"; 80 //div_banner.style.color=this.bannerFontColor; 81 //div_banner.style.fontWeight="bold"; 82 83 //this.changeYearBack=obj_p. 84 85 var len=this.arr_bannerp.length; 86 var sum_left=0; 87 for(var i=0;i<len;i++)//banner上调整年月的按钮 88 { 89 var bannerp=this.arr_bannerp[i]; 90 var btn=document.createElement("button"); 91 btn.id=bannerp.id; 92 btn.style.position="absolute"; 93 btn.style.backgroundColor=this.bannerBackColor; 94 btn.style.border="0px"; 95 btn.style.padding="0px"; 96 btn.style.textAlign="center"; 97 btn.style.color=this.bannerFontColor;//button这个属性并不会自动继承 98 btn.style.fontWeight="bold"; 99 btn.style.fontSize=this.contentFontSize+2+"px";100 btn.style.height="100%";101 btn.style.lineHeight=this.h2+"px";102 btn.style.width=bannerp.width+"px";103 btn.style.left=sum_left+bannerp.marginLeft+"px";104 btn.innerText=bannerp.text;105 btn.onclick=bannerp.onclick;106 sum_left+=(bannerp.width+bannerp.marginLeft);107 this[btn.id]=btn;108 div_banner.appendChild(btn);109 }110 div.appendChild(div_banner);111 this.paddingSize=obj_p.paddingSize||6;112 113 this.gridBackColor=obj_p.gridBackColor||"#eeeeee";//单元格背景颜色114 this.gridColor=obj_p.gridColor||"#000000";//本月单元格的文字颜色115 this.gridColor0=obj_p.gridColor0||"#888888";//连带显示的非本月单元格的文字颜色116 this.hoverBorderColor=obj_p.hoverBorderColor||"#888888";//鼠标移入可选单元格后的边框颜色117 this.enableBackColor=obj_p.enableBackColor||"rgb(207,232,252)";//可以被选择的单元格的背景颜色118 this.enableBackColorPicked=obj_p.enableBackColorPicked||"rgb(2.........