原生js实现日历详解

html源码:

 <div class="calender">
      <div class="calender_header">
        <div class="calender_left_btn">&lt;</div>
        <div class="calender_year"></div>
        <div class="calender_right_btn">&gt;</div>
      </div>
      <div class="calender_body">
        <div class="calender_row">
          <div class="calender_weekbox">日</div>
          <div class="calender_weekbox">一</div>
          <div class="calender_weekbox">二</div>
          <div class="calender_weekbox">三</div>
          <div class="calender_weekbox">四</div>
          <div class="calender_weekbox">五</div>
          <div class="calender_weekbox">六</div>
        </div>
        <div class="calender_dayrows"></div>
      </div>
    </div>

css源码:

.calender{
    width: 90%;
    margin: 50% 5%;
    float: left;
    border: solid 1px rgb(211, 107, 107);
    /* background:url('../images/calender-bg.png') no-repeat;
    background-size:100% 100%;  */
    box-shadow: rgb(134, 127, 127) 0px 0px 30px 5px inset;
}
.calender_header{
    display: flex;
    justify-content: space-between;
    height: 30%;
}
.calender_header span{
    display: block;
    margin-top: 9%;
    text-align: center;
}
.calender_left_btn,
.calender_right_btn{
    width: 2%;
    height: 2%;
    color: #fff;
    text-align: center;
    line-height: 100%;
    cursor: pointer;
    margin-top: 3%;
}
.calender_left_btn{
    float: left;
    margin-left: 4%;
}
.calender_right_btn{
    float: right;
    margin-right: 4%;
}
.calender_year{
    text-align: center;
    /* line-height: 1%; */
    color: #fff;
}
.calender_body{
    border-right: 1px solid #9e9e9e;    
    border-bottom: 1px solid #9e9e9e;
}
.calender_row{
    overflow: hidden;
    width: 100%;
    
}
.calender_weekbox{
    float: left;
    color:#fff;
    margin-bottom: 2%;
    margin-top: 13%;
    margin-right: 4.4%;
    margin-left: 2%;
    font-size: 16px;
    text-align: center;
}
.calender_days_rows{
    overflow: hidden;
    }
.day_box,.today{
    float: left;    
    width: 13.4%;    
    height: 30px;    
    border-top: 1px solid #9e9e9e;    
    border-left: 1px solid #9e9e9e;    
    text-align: center;    
    line-height: 225%;
    }
.today{ 
   background: #ff5722;
   }

重点介绍js逻辑:
实现流程:
1:获得当前的日期
2:判断当前的日期是平年还是闰年
3:判断当前月数的天数
4:判断当前月数第一天是星期几
5:根据当前月数天数和第一天星期几来判断行数
6:进行渲染
具体实现过程:
1:获取年月日

let curTime = new Date(),
    curYear = curTime.getFullYear(),
    curMonth = curTime.getMonth(),
    curDate = curTime.getDate();

平年或者闰年判断函数:
判断条件 1:年份能能整除4且不能整除100
2:能整除400

function isLeapYear(year){    
    return (year%400 === 0) || ((year%4 === 0) && (year%100 !== 0))
}

2:利用数组把每月的天数进行储存

  let daysInMonth = [31, isLeapYear(curYear) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];  

3:确定今天日期所在月的第一天是星期几

  let firstDayInMonth = new Date(curYear, curMonth, 1),
        firstDayWeek = firstDayInMonth.getDay(); 

4:确定这个月需要的行数

let calendarRows = Math.ceil((firstDayWeek + daysInMonth[curMonth])/7);    

5: 利用内外循环渲染日历得到每一行以及行中的每一天
利用索引值将日期与星期同步
对日期进行判断 过滤掉无用的日期(即不进行表格渲染 显示为空白即可)

 let rows = [];   
    for(let i = 0; i < calendarRows; i++){
                rows[i] = `<div class="calender_days_rows">`;      
    for(let j = 0; j < 7; j++){        
                    let order= i*7 + j,
                    date = order- firstDayWeek + 1;              
                    if(date <= 0 || date > daysInMonth[curMonth]){
                    rows[i] += `<p class="day_box" style="color:#fff"></p>`
                }else if(date === curDate){
                    rows[i] += `<p class="day_box today" style="color:#fff">${date}</p>`
                }else{
                    rows[i] += `<p class="day_box" style="color:#fff">${date}</p>`
                }
            }
            rows[i] += `</div>`
     }   
    }

6:将渲染好的每一行连接显示起来

let dataStr = rows.join('');    
    // console.log(dateStr);
    document.querySelector('.calender_dayrows').innerHTML = dataStr;

:7:首行年份切换设置

let leftBtn = document.querySelector('.calender_left_btn');
    rightBtn = document.querySelector('.calender_right_btn');
    // 向左切换月份
leftBtn.addEventListener('click', function(){
    curMonth--;    
    if(curMonth < 0){
        curYear -= 1;
        curMonth = 11;
    }
    ws(curYear, curMonth);
})
// 向右切换月份
rightBtn.addEventListener('click', function(){
    curMonth++;    
    if(curMonth > 11){
        curYear += 1;
        curMonth = 0;
    }
    ws(curYear, curMonth);
})

运行结果显示:
在这里插入图片描述
js整体源码:

let curTime = new Date(),
    curYear = curTime.getFullYear(),
    curMonth = curTime.getMonth(),
    curDate = curTime.getDate();
    function isLeapYear(year){    
    return (year%400 === 0) || ((year%4 === 0) && (year%100 !== 0))
}
function ws(curYear, curMonth){    
document.querySelector('.calender_year').innerHTML = `<span>${curYear}年${curMonth + 1}月</span>`;      
let daysInMonth = [31, isLeapYear(curYear) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];    
let firstDayInMonth = new Date(curYear, curMonth, 1),
        firstDayWeek = firstDayInMonth.getDay();     
        let calendarRows = Math.ceil((firstDayWeek + daysInMonth[curMonth])/7);    
        let rows = [];    
        // 外循环渲染日历的每一行    
        for(let i = 0; i < calendarRows; i++){
            rows[i] = `<div class="calender_days_rows">`;        
        // 内循环渲染日历的每一天        
            for(let j = 0; j < 7; j++){           
        // 利用order 索引与当前月第一天星期几来确定当前月的日期            
            let order = i*7 + j,
                date = order - firstDayWeek + 1;            
                // 过滤掉无效日期、渲染有效日期            
                if(date <= 0 || date > daysInMonth[curMonth]){
                rows[i] += `<p class="day_box" style="color:#fff"></p>`
            }else if(date === curDate){
                rows[i] += `<p class="day_box today" style="color:#fff">${date}</p>`
            }else{
                rows[i] += `<p class="day_box" style="color:#fff">${date}</p>`
            }
        }
        rows[i] += `</div>`
    }   
    let dataStr = rows.join('');    
    // console.log(dateStr);
    document.querySelector('.calender_dayrows').innerHTML = dataStr;
}
ws(curYear, curMonth);
let leftBtn = document.querySelector('.calender_left_btn');
    rightBtn = document.querySelector('.calender_right_btn');
    // 向左切换月份
leftBtn.addEventListener('click', function(){
    curMonth--;    
    if(curMonth < 0){
        curYear -= 1;
        curMonth = 11;
    }
    ws(curYear, curMonth);
})
// 向右切换月份
rightBtn.addEventListener('click', function(){
    curMonth++;    
    if(curMonth > 11){
        curYear += 1;
        curMonth = 0;
    }
    ws(curYear, curMonth);
})
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值