js萬年歷,麻雀雖小五臟俱全,由原生js編寫


對於前端來說,我們可能見到最多的就是各種各樣的框架,各種各樣的插件了,有各種各樣的功能,比如輪播啊,日歷啊,給我們提供了很大的方便,但是呢?我們在用別人這些寫好的插件,框架的時候,有沒有試着問一問自己?這些東西都是怎么寫出來的?現在我們以一個萬年歷為例,介紹下怎么寫出來,別人那個看似小巧的萬年歷,又蘊含着怎樣的構思,我覺得這才是前端的魅力所在。

廢話不多說了,先看看我做的效果圖:

說一下具體的思路先:首先js能給我們的就只是一個日期函數date();我們只能知道當前時間是哪年哪月哪日哪時哪分哪秒,時分秒這里不用(待會再說為什么不用),那我們怎么做出來呢?

1、其實這個日歷實際上是一個上頭的div+下方的表格table組合而成,這是第一步

2、說第2步之前呢?我先貼下html的代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>萬年歷</title>
    <link rel="stylesheet" href="dorseyCh.css" type="text/css">
    <script src="dorseyCh.js" type="text/javascript"></script>
</head>
<body>
<div id="dsCalendar">
</div>
</body>
</html>

可以看到就是一個div指定到某個id上。跟我們插件類似,為什么先貼代碼,因為這里組成萬年歷的div跟table是通過js創建出來的。

怎么創建呢?這里列兩個關鍵函數:

(父元素).appendChild(子元素).添加子元素

(父元素).removeChild(子元素).刪除子元素

3、創建了元素之后呢?得有內容,表格的每個單元格填什么?怎么填?

這里我說下我的思路,可能有大神會有更好的,僅供參考:

1、首先我們獲取每個月的第1天,以及這一天是星期幾(date(年,月,1).getDay());這部分其實應該都會。

2、我們每個月的天數是固定的,除了2月份閏年多一天之外其他是固定的,這就很容易聯想到做一個數組,通過查表的方式來獲取每個月的天數。

3、接下來呢?最后一天跟第一天知道了,我們怎么把這些給填進去呢?也不難,上面創建的table是一個7*6的表格,先默認把7*6的表格從1~42全部填進去,然后呢,因為我們第一天是星期幾是知道的,把這42個數都去減掉星期幾對應的那個數,你會發現嘿嘿在對應的星期上就填出了個0,再加1就OK了,接下來呢,把不用的都去掉,什么意思呢?因為你原來是1~42,現在變成了-x到42-x(這個x就是星期幾代表的那個數),然后呢把小於0且大於對應月份天數的數全部清除掉,剩余的你會發現就是一個日歷的一頁了。

4、點擊換頁

四個按鈕也很簡單,只需要對應按鈕點擊一下,比如年-的按鈕,那就把對應的年份減1,同時這里需要說的是換頁,這個怎么做呢?

也很簡單,把table刪掉,再重新弄個table進去(這時候的table里面某個月或是某年對應的值是改變了的)

這個方法我總覺得比較耗費資源,當然應該會有更好的辦法,這里僅供參考。

5、換頁了,但是萬年歷還有一個顯示細節的欄目,顯示對應日期的,這個怎么搞?

也很簡單,通過innerHTML寫入,但寫入啥呢?對應的年月日跟星期咯。

6、還有一個細節就是我們在點日歷的時候,點擊后,顯示詳情頁會變成你點擊的那一天,這又得怎么搞?

也不難,你忘了js本身就有獲取元素標簽的值的函數,把獲取的值動態顯示到詳情頁即可,接下來還有一個小問題,顯示欄不是還有星期么?得怎么顯示啊?嘿嘿,這個你發現沒,你點擊的那個小單元格它是在42個格里都有對應的位置的,比如0,7,14,21都是對應了星期一是吧?這樣你會了吧,還是不會的話,這42個值是不是可以余7,剩下的數值就是跟星期一一對應了,說到一一對應,嗯又可以聯想到列數組查表了哈。

基本的思路就是這樣,其他小細節,小改樣式的就不細說了,沒意思,樣式什么的各位可以自己改。

好啦!最重要的代碼來啦,感謝你聽了我啰嗦這么多。

css部分:(這里面我為了方便調試給外部div定義了位置,插件最好不要,不會亂,讓用這個插件的人自己去調位置)

#dsCalendar{width:500px;height:396px;margin:100px auto;border-radius:20px;
    border:1px solid black;box-shadow:5px 5px #222;box-sizing: border-box}

#dsCalendar table{width:500px;height:336px;border:1px solid black;box-sizing:border-box;
    background:url(images/calendar.jpg) 100%;font:25px Times New Roman;text-align: center;border-radius:20px;}
#dsCalendar table thead{width:500px;border-radius:20px;}
/*#dsCalendar table thead{width:500px;height:56px;background:red;}*/
#dsCalendar table thead tr td{color:black;height:80px;}

#dsCalendar table tbody tr td{color:red;cursor:pointer;height:36px;border-radius:36px;}
#dsCalendar table tbody tr td:hover{background:skyblue;color:black;}

#dsCalendar div{width:500px;height:60px;border-radius:60px;}
#dsCalendar div span,#dsCalendar div span img{width:40px;height:40px;border-radius:50px;}
#dsCalendar div span{float:left;box-sizing:border-box;cursor:pointer;margin-top:10px;}

#dsCalendar div .yBtn,#dsCalendar div .yBtn img{width:60px;height:60px;border-radius:60px;margin-top:0;}

#dsCalendar #cDetail{float:left;width:300px;height:60px;border:1px solid black;box-sizing:border-box;
font:20px Times New Roman;text-align: center;line-height:60px;}
#dsCalendar div:after{clear:both;content:'';display:block;}

js部分:(開頭說了那么多插件插件,這里算是勉強可以當成個人類庫使用,沒有插件框架那么嚴謹,主要是思路)

window.onload=function(){
  (function dsCalendar(){
    var oCalendar=document.getElementById('dsCalendar');

    /*上面控制欄所有內容*/
    var oDiv=document.createElement('div');
    oDiv.innerHTML='<span class="yBtn"><img src="images/y_left.png" alt=""></span>' +
        '<span><img src="images/m_left.png" alt=""></span><div id="cDetail"></div>' +
        '<span><img src="images/m_right.png" alt=""></span>'+
        '<span class="yBtn"><img src="images/y_right.png" alt=""></span>';
    oCalendar.appendChild(oDiv);
    /*日歷內容解析*/
    var oDate=new Date();
    var oYear=oDate.getYear();
    var isLeap=oYear%400==0?1:((oYear%100!=0&&oYear%4==0)?1:0);
    var aMouth=[31,28+isLeap,31,30,31,30,31,31,30,31,30,31];//創建月份尾數表,作為每張日歷最后一個數
    var aWeek=['日','一','二','三','四','五','六'];
    var y=oDate.getFullYear();
    var m=oDate.getMonth(),
        d=oDate.getDate(),
        w=oDate.getDay();
        //hour=oDate.getHours(),
        //min=oDate.getMinutes(),
        //sec=oDate.getSeconds();
    var oDetail=document.getElementById('cDetail');//顯示當前日期的欄目
    var oSpan=oDiv.getElementsByTagName('span');   //4個按鈕

    function update(){
      /*table里面的所有內容*/
      var cTable=document.createElement('table'); //創建table
      var cTHead=document.createElement('thead'); //創建thead
      var cTBody=document.createElement('tbody'); //創建tbody
      /*無中生有,通過javascript創造一個table表格*/
      var cTr0=document.createElement('tr');
      for(var k=0;k<7;k++){
        var cTd0=document.createElement('td');
        cTd0.innerHTML=aWeek[k];
        cTr0.appendChild(cTd0);
      }
      cTHead.appendChild(cTr0);
      cTable.appendChild(cTHead);


      var firstDate=new Date(y,m,1); //獲取當月第一天
      var dayOfWeek=firstDate.getDay();//獲取當月的第一天是星期幾
      for(var i=0;i<6;i++){
        var ctr=document.createElement('tr');
        for(var j=0;j<7;j++){
          var re=i*7+j;
          var re1=re-dayOfWeek+1;
          var ctd=document.createElement('td');
          if(re1<=0||re1>aMouth[m]){
            ctd.innerHTML='';
          }
          else{
            ctd.innerHTML=re1;
            if(re1==d&&m==oDate.getMonth()&&y==oDate.getFullYear()){
              ctd.style.color='black';
              ctd.style.border='1px dasher black';
            }
          }
          ctr.appendChild(ctd); //將創造出來的td插入到tr中
        }
        cTBody.appendChild(ctr); //將創造出來的tr插入到tbody中
      }
      cTable.appendChild(cTBody); //將創造出來的tbody插入到table中
      oCalendar.appendChild(cTable);//將創造出來的table插入到指定id的div中,完成一個完整table的創建

      /*在控制欄的中部加入當天的時間*/

      oDetail.innerHTML=y+'年'+(m+1)+'月'+d+'日'+' '+'星期'+aWeek[w];

      //4個按鈕的功能函數
      for(var a=0;a<oSpan.length;a++){
        oSpan[a].index=a;
        oSpan[a].onclick=function(){
          for(var i=0;i<oSpan.length;i++){
            oSpan[i].style.background='';
          }
          this.style.background='yellow';
          switch(this.index){
            case 0:y-=1;break;
            case 1:{
                      m-=1;
                      if(m<0){
                        m=11;
                        y-=1;
                      }
            }break;
            case 2:{
                      m+=1;
                      if(m>11){
                      m=0;
                      y+=1;
                      }
            }break;break;
            case 3:y+=1;break;
          }
          oCalendar.removeChild(cTable);
          update();
          oDetail.innerHTML=y+'年'+(m+1)+'月'+d+'日'+' '+'星期'+aWeek[w];
        };
      }

      //點擊任意一天的功能函數
      //var ctr1=cTBody.getElementsByTagName('tr');
      var ctd1=cTBody.getElementsByTagName('td');
      for(var i=0;i<ctd1.length;i++){
        ctd1[i].index=i;
        ctd1[i].onclick=function(){
          for(var i=0;i<ctd1.length;i++){
            ctd1[i].style.background='';
          }
          ctd1[this.index].style.background='skyblue';
          oDetail.innerHTML=y+'年'+(m+1)+'月'+ctd1[this.index].innerText+'日'+' '+'星期'+aWeek[(this.index%7)];
          console.log(this.index);
        }
      }
      console.log(ctd1.length);

    }
    update();
  })();
};

好了,基本的都在那,里面加了一些小資源文件(圖片)就不貼了,希望對各位在javascript有所幫助。

javascript是開源的,不止js,很多都是開源的,給了我們程序員無窮無盡的的資料,我們要珍惜,分享快樂!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM