一個簡單橫向javascript日期控制項_時間日期

來源:互聯網
上載者:User
具體要求就是:
1、日期表格橫向佔滿頁面。
2、每個月的日期列表橫向顯示在一排,而不是像網上的很多日期控制項顯示一個方塊。
3、要求只有年月日可選,選擇年或月後自動更新對應日期(這個每個日期控制項都有的)。
4、預設顯示當前年月,高亮當前日期,並顯示當前的周次(本年第幾周)和星期幾。
5、選擇某個日期後高亮顯示當前日期,並自動更新周次和星期顯示。
6、提供介面,可以設定特定日期的顯示樣式。
6、其他就是一些介面展示的問題了。

想著就是一個日期控制項,做著也比較簡單,不過比較特別是橫向的,第一次聽說這種需求的!
偶還是第一次寫日曆類的東西,不過這次的麻煩還是在於周次的計算上和最後提供的設定特定日期的介面實現上,但經過一番分析也很好的解決了。
主要幾個總結:
1、使用了閉包,隱藏內建函式及變數,防止變數汙染。最後只提供一個對外介面:setDateStyle
2、計算每年二月的天數不是通過判斷閏年的辦法,而是通過判斷是否2月29日存在,如果不存在則為28天。
3、計算周次要先計算當前日期是本年的第幾天,同時要考慮本年1月1日是星期幾,然後計算即可得出。
4、setDateStyle支援單個日期樣式的傳入,也支援多個日期樣式的設定。對於樣式的更新主要採用數組合并字元竄,並採用字串的indexOf方法匹配並執行樣式的設定。
5、CSS/JS/HTML相分離,便於維護。函數模組化便於重用。
複製代碼 代碼如下:

var logDateControl=(function(){
  var curSelEl;  //當前選中的日期
  var styleData=[],dataStyle={};
  //擷取指定id的元素
  var $=function(id){return document.getElementById(id)}
  //計算指定日期是第幾周(預設為當前日期),該計算方法比較嚴密準確
  var calWeek=function(dt){
    var calDay=dt||new Date();  //當前要計算的時間
    var firstDay=new Date(calDay.getFullYear(),0,1);  //本年第一天
    //計算當前是本年的第幾天,00:00為當天開始
    var daysAll=Math.floor((calDay-firstDay)/1000/60/60/24)+1;  
    //本年第一天星期幾
    var firstDayWeekday=firstDay.getDay();  
    //該結果加到第一周的周一,便於後面計算
    var diffDay=firstDayWeekday==0?6:firstDayWeekday-1;  
    daysAll=daysAll+diffDay;
    return Math.ceil(daysAll/7);  //返回計算結果
  }
  //計算一個月多少天,年份4位元字,月份1-2位元字(應該是js日期格式如1月傳入0),資料非法返回-1
  var getDaysLen=function(year,month){
    if(!(/^\d{4}$/.test(year)&&/^\d{1,2}$/.test(month))){return -1}
    var monthDays=[31,28,31,30,31,30,31,31,30,31,30,31]
    //存在2月29日
    if(month==1&&new Date(year,1,29).getMonth()==1){monthDays[1]=29}
    return monthDays[month]
  }
  //顯示日期列表,傳入年、月(按日常月份傳入。如二月傳入2)、及顯示位置
  var displayDayList=function(year,month,pos){
    var daysList=[];
    var cells1=$(pos).rows[0].cells;
    var cells2=$(pos).rows[1].cells;
    var daysArr=['日','一','二','三','四','五','六'];
    //下面的month-1轉換為js月份表示
    for(var i=1,l=getDaysLen(year,--month)+1;i<l;i++){
      var wd=new Date(year,month,i).getDay();
      cells1[i-1].className="";
      if(wd==0||wd==6){cells1[i-1].className="weekEnd";}  //為周末添加特殊樣式
      //_oldCls儲存當前日期的預設樣式
      cells1[i-1].innerText=daysArr[wd];
      cells2[i-1].className="unSelectDay";
      cells2[i-1].setAttribute("_oldCls","unSelectDay");
      cells2[i-1].innerText=i>9?i:"0"+i;
      //匹配使用者自訂樣式
      var dtStr=year+"|"+(month+1)+"|"+i;
      if((","+styleData.join(',')+",").indexOf(","+dtStr+",")>-1){
        cells2[i-1].className="unSelectDay "+dataStyle[dtStr];
        cells2[i-1].setAttribute("_oldCls","unSelectDay "+dataStyle[dtStr]);
      }
    }
    //如果是當前月則選中當日
    if(new Date().getMonth()==month){
      curSelEl=cells2[new Date().getDate()-1];
      curSelEl.className="selectDay";
    }
    for(var j=i-1;j<31;j++){
      cells1[j].className=cells2[j].className="";
      cells1[j].innerHTML=cells2[j].innerHTML="  ";
    }
    $(pos).onclick=function(){changeInfo()}
  }
  //根據選擇的值進行處理周次和周幾的調整,可以直接傳入儲存日期內容的dom元素,或者函數根據點擊位置判斷
  var changeInfo=function(e){
    e=e||event;
    var el=e.target||e.srcElement||e;  //最後一個e:可能是傳入的對象
    var day=el.innerText;
    if(!/^\d{1,2}$/.test(day)) return;  //如果不是日期什麼都不做
    //恢複之前選中日期的樣式
    if(curSelEl){curSelEl.className=curSelEl.getAttribute("_oldCls")}
    curSelEl=el;  //儲存當前處理的元素
    //更新選中日期的樣式
    el.className="selectDay";
    var dt=new Date($("year").value,$("month").value-1,day);
    //更新資訊
    $("day").value=day;  //日期
    $("weekday").value=['日','一','二','三','四','五','六'][dt.getDay()];  //星期幾
    $("week").value=calWeek(dt);  //第幾周
  }
  //初始化
  window.attachEvent("onload",function(){
    var curDate=new Date(),curYear=curDate.getFullYear();
    //顯示上下十年
    for(var i=-10;i<10;i++){$("year").add(new Option(curYear+i,curYear+i))}
    $("year").selectedIndex=10;  //預設選中當前年份
    $("month").selectedIndex=curDate.getMonth();  //當前月份
    $("day").value=curDate.getDate();  //當前日期
    $("weekday").value=['日','一','二','三','四','五','六'][curDate.getDay()];  //當前星期幾
    $("week").value=calWeek();  //當前第幾周
    //改變日期或年份更新日期列表
    $("year").onchange=$("month").onchange=function(){displayDayList($("year").value,$("month").value,"daysList")};
    //顯示當月日期列表,並高亮當天的日期
    displayDayList(curDate.getFullYear(),curDate.getMonth()+1,"daysList");
  });

  //對外設定樣式的介面。
  //格式:([2007,10,12],"color:#f00") ([[2007,10,20],[2007,11,25]],"color:#00f")
  //如果月份小於10不要帶0
  var setDateStyle=function(dateArr,style){
    if(typeof dateArr!="object")return;
    if(dateArr instanceof Array){
      if(dateArr[0] instanceof Array){
        for(var i=0;i<dateArr.length;i++) setDateStyle(dateArr[i],style);
      }
      var dataStr=dateArr.join('|');
      styleData.push(dataStr);
      dataStyle[dataStr]=style;
      return;
    }
  }
  //對外介面
  return {setDateStyle:setDateStyle}
})();
//測試樣式設定
logDateControl.setDateStyle([[2007,12,15],[2007,11,12]],"test");

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> new document </title> <meta name="generator" content="editplus" /> <meta name="author" content="" /> <meta name="keywords" content="" /> <meta name="description" content="" /> <style type="text/css"> *{font-size:14px} /*日期最外層*/ #logCalendar{width:950px;border-top:1px solid #ccc;border-left:1px solid #ccc} /*日期內部所有儲存格*/ #logCalendar td{ border-right:1px solid #ccc;border-bottom:1px solid #ccc; padding-left:5px;text-align:center; height:22px;line-height:22px; } #daysList{border-top:1px solid #ccc;border-left:1px solid #ccc} /*日期列表所有儲存格*/ #daysList td{text-align:center;height:22px} /*周次及星期幾的輸入框*/ .bd{border:0;text-align:center;color:#00f} /*日期預設樣式*/ .unSelectDay{ color:#00f;font-weight:normal; padding:3px;cursor:pointer; text-decoration:underline } /*當前點擊的日期樣式*/ .selectDay{color:#fff;font-weight:bold;background:#FEB0B0;padding:1px;text-decoration:none;cursor:normal} /*周末樣式*/ .weekEnd{color:#f00} .test{color:#f00;text-decoration:none} </style> <script type="text/javascript"> //2007-12-21 工作日誌日期組件 yanwei //使用閉包隱藏所有變數和函數,防止與外界衝突 var logDateControl=(function(){ var curSelEl; //當前選中的日期 var styleData=[],dataStyle={}; //擷取指定id的元素 var $=function(id){return document.getElementById(id)} //計算指定日期是第幾周(預設為當前日期),該計算方法比較嚴密準確 var calWeek=function(dt){ var calDay=dt||new Date(); //當前要計算的時間 var firstDay=new Date(calDay.getFullYear(),0,1); //本年第一天 //計算當前是本年的第幾天,00:00為當天開始 var daysAll=Math.floor((calDay-firstDay)/1000/60/60/24)+1; //本年第一天星期幾 var firstDayWeekday=firstDay.getDay(); //該結果加到第一周的周一,便於後面計算 var diffDay=firstDayWeekday==0?6:firstDayWeekday-1; daysAll=daysAll+diffDay; return Math.ceil(daysAll/7); //返回計算結果 } //計算一個月多少天,年份4位元字,月份1-2位元字(應該是js日期格式如1月傳入0),資料非法返回-1 var getDaysLen=function(year,month){ if(!(/^\d{4}$/.test(year)&&/^\d{1,2}$/.test(month))){return -1} var monthDays=[31,28,31,30,31,30,31,31,30,31,30,31] //存在2月29日 if(month==1&&new Date(year,1,29).getMonth()==1){monthDays[1]=29} return monthDays[month] } //顯示日期列表,傳入年、月(按日常月份傳入。如二月傳入2)、及顯示位置 var displayDayList=function(year,month,pos){ var daysList=[]; var cells1=$(pos).rows[0].cells; var cells2=$(pos).rows[1].cells; var daysArr=['日','一','二','三','四','五','六']; //下面的month-1轉換為js月份表示 for(var i=1,l=getDaysLen(year,--month)+1;i<l;i++){ var wd=new Date(year,month,i).getDay(); cells1[i-1].className=""; if(wd==0||wd==6){cells1[i-1].className="weekEnd";} //為周末添加特殊樣式 //_oldCls儲存當前日期的預設樣式 cells1[i-1].innerText=daysArr[wd]; cells2[i-1].className="unSelectDay"; cells2[i-1].setAttribute("_oldCls","unSelectDay"); cells2[i-1].innerText=i>9?i:"0"+i; //匹配使用者自訂樣式 var dtStr=year+"|"+(month+1)+"|"+i; if((","+styleData.join(',')+",").indexOf(","+dtStr+",")>-1){ cells2[i-1].className="unSelectDay "+dataStyle[dtStr]; cells2[i-1].setAttribute("_oldCls","unSelectDay "+dataStyle[dtStr]); } } //如果是當前月則選中當日 if(new Date().getMonth()==month){ curSelEl=cells2[new Date().getDate()-1]; curSelEl.className="selectDay"; } for(var j=i-1;j<31;j++){ cells1[j].className=cells2[j].className=""; cells1[j].innerHTML=cells2[j].innerHTML="  "; } $(pos).onclick=function(){changeInfo()} } //根據選擇的值進行處理周次和周幾的調整,可以直接傳入儲存日期內容的dom元素,或者函數根據點擊位置判斷 var changeInfo=function(e){ e=e||event; var el=e.target||e.srcElement||e; //最後一個e:可能是傳入的對象 var day=el.innerText; if(!/^\d{1,2}$/.test(day)) return; //如果不是日期什麼都不做 //恢複之前選中日期的樣式 if(curSelEl){curSelEl.className=curSelEl.getAttribute("_oldCls")} curSelEl=el; //儲存當前處理的元素 //更新選中日期的樣式 el.className="selectDay"; var dt=new Date($("year").value,$("month").value-1,day); //更新資訊 $("day").value=day; //日期 $("weekday").value=['日','一','二','三','四','五','六'][dt.getDay()]; //星期幾 $("week").value=calWeek(dt); //第幾周 } //初始化 window.attachEvent("onload",function(){ var curDate=new Date(),curYear=curDate.getFullYear(); //顯示上下十年 for(var i=-10;i<10;i++){$("year").add(new Option(curYear+i,curYear+i))} $("year").selectedIndex=10; //預設選中當前年份 $("month").selectedIndex=curDate.getMonth(); //當前月份 $("day").value=curDate.getDate(); //當前日期 $("weekday").value=['日','一','二','三','四','五','六'][curDate.getDay()]; //當前星期幾 $("week").value=calWeek(); //當前第幾周 //改變日期或年份更新日期列表 $("year").onchange=$("month").onchange=function(){displayDayList($("year").value,$("month").value,"daysList")}; //顯示當月日期列表,並高亮當天的日期 displayDayList(curDate.getFullYear(),curDate.getMonth()+1,"daysList"); }); //對外設定樣式的介面。 //格式:([2007,10,12],"color:#f00") ([[2007,10,20],[2007,11,25]],"color:#00f") //如果月份小於10不要帶0 var setDateStyle=function(dateArr,style){ if(typeof dateArr!="object")return; if(dateArr instanceof Array){ if(dateArr[0] instanceof Array){ for(var i=0;i<dateArr.length;i++) setDateStyle(dateArr[i],style); } var dataStr=dateArr.join('|'); styleData.push(dataStr); dataStyle[dataStr]=style; return; } } //對外介面 return {setDateStyle:setDateStyle} })(); //測試樣式設定 logDateControl.setDateStyle([[2007,12,15],[2007,11,12]],"test"); </script> </head> <body> <table cellpadding="3" cellspacing="0" id="logCalendar"> <tr> <td>第<input type="text" name="week" class="bd" readonly size="2">周</td> <td>星期<input type="text" name="weekday" class="bd" readonly size="2"></td> <td rowspan="2" > <table width="100%" cellpadding="3" height="100%" cellspacing="0" id="daysList"> <tr> <td></td><td></td><td></td><td></td><td></td> <td></td><td></td><td></td><td></td><td></td> <td></td><td></td><td></td><td></td><td></td> <td></td><td></td><td></td><td></td><td></td> <td></td><td></td><td></td><td></td><td></td> <td></td><td></td><td></td><td></td><td></td><td></td> </tr> <tr> <td></td><td></td><td></td><td></td><td></td> <td></td><td></td><td></td><td></td><td></td> <td></td><td></td><td></td><td></td><td></td> <td></td><td></td><td></td><td></td><td></td> <td></td><td></td><td></td><td></td><td></td> <td></td><td></td><td></td><td></td><td></td><td></td> </tr> </table> </td> </tr> <tr> <td><select name="year" id="year"></select>年 <select name="month" id="month"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> <option value="6">6</option> <option value="7">7</option> <option value="8">8</option> <option value="9">9</option> <option value="10">10</option> <option value="11">11</option> <option value="12">12</option> </select>月</td> <td>日期<input type="text" name="day" size="2" class="bd" id="day"></td> </tr> </table> </body> </html>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.