zoukankan      html  css  js  c++  java
  • 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{500px;height:396px;margin:100px auto;border-radius:20px;
        border:1px solid black;box-shadow:5px 5px #222;box-sizing: border-box}
    
    #dsCalendar table{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{500px;border-radius:20px;}
    /*#dsCalendar table thead{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{500px;height:60px;border-radius:60px;}
    #dsCalendar div span,#dsCalendar div span img{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{60px;height:60px;border-radius:60px;margin-top:0;}
    
    #dsCalendar #cDetail{float:left;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,很多都是开源的,给了我们程序员无穷无尽的的资料,我们要珍惜,分享快乐!

  • 相关阅读:
    ls 按大小排序 按时间排序
    【u035】奶牛的电信
    【record】#10
    【record】10.30..11.6
    【33.33%】【codeforces 608C】Chain Reaction
    【44.19%】【codeforces 608D】Zuma
    【22.73%】【codeforces 606D】Lazy Student
    【27.40%】【codeforces 599D】Spongebob and Squares
    【26.67%】【codeforces 596C】Wilbur and Points
    【13.91%】【codeforces 593D】Happy Tree Party
  • 原文地址:https://www.cnblogs.com/dorseych/p/8643853.html
Copyright © 2011-2022 走看看