使用JS实现简单的日历插件

一、简要介绍

实现一个如下图所示的日历,这边主要提供html部分和js部分的代码,css部分大家自行编写哦。

请添加图片描述

二、基础代码

html部分

其实就是一个div容器,为其设置相应的id值。

	<div id="calendar" class="calendar">

	</div>

js部分

我们先来简单梳理一下需要完成的步骤:
将表格渲染出来,不然这个容器就是空的:

	var calBox = document.getElementById("calendar");
    var str = "<div class='title'>\
                <a id='calendar-pre'>&lt;上月(\
                " + preMonth + "月)</a><label>\
                "+year+"年</label><label>" +month+"\
                月</label> <a id='calendar-next'>下月\
                ("+nextMonth+"月)&gt;</a> </div>"
    str += "<table class='calendar-table'>"
    str += "</table>"
    calBox.innerHTML = str;

在进行完这一部分的代码编写后,就可以将表格渲染出来,但是这时表格是空的,我们需要获取时间,并将时间渲染进表格,首先是获取时间,使用到了Date对象:

	var now = new Date();//当前日期
	var year = now.getFullYear();// 年份
	var month = now.getMonth() + 1;// 月份
	var preMonth = now.getMonth();// 上个月
	var nextMonth = month + 1;// 下个月
	var days,whatday,predays; //days表示当月天数,predays表示上个月天数,whatday表示当月一号所在的是周几
	var weeks = ['一','二','三','四','五','六','日'];//设置头部是从周一开始还是周日开始
	var begin;//传入参数,用于设置上一个月还剩几天的天数显示
	function setNewDate(){//设置日期的方法
	    if(month == 1){ //当前月为1月时,上一个月显示为12月
	        preMonth = 12;
	    }
	    if(month == 12){ //当前月为12月时,下一个月显示为1月
	        nextMonth = 1;
	    }
	    now.setFullYear(year, month, 0);
	    days = now.getDate();//当前月天数
	    now.setDate(1);//获取的是1号
	    whatday = now.getDay();// 获取1号在周几
	    now.setFullYear(year, month - 1, 0);
	    predays = now.getDate();// 上个月天数
	    begin = predays - whatday + 2; // 设置上一个月还剩几天的天数显示
	    getCalendar(weeks, begin, whatday - 1); //传入参数,调用getCalender方法
	}
	setNewDate(); // 初始化日期

getCalendar方法,主要是对表格进行渲染:

function getCalendar(weeks, begin, whichday){
    var calBox = document.getElementById("calendar"); //获取日历的dom对象
    var str = "<div class='title'>\
                <a id='calendar-pre'>&lt;上月(\
                " + preMonth + "月)</a><label>\
                "+year+"年</label><label>" +month+"\
                月</label> <a id='calendar-next'>下月\
                ("+nextMonth+"月)&gt;</a> </div>" //渲染表格基础信息
    str += "<table class='calendar-table'>"
    str += "<tr>"
    for(var i = 0; i < 7;i++){ //渲染头部
        str += "<th>" + weeks[i] + "</th>"
    }
    str += "</tr>";
    var line = Math.ceil((days + whichday) / 7); // 行数
    var curIndex = 1; //当前天
    var start = begin; //上一个月遗留的天数显示
    var flag = false; //这个月的天数是否渲染完成
    for(var l = 0; l < line; l++){ 
        str += "<tr>";
        for(var i = 0; i < 7; i++){ //一周七天
            if(i < whichday && l == 0){ //当i小于一号所在的周几数就表示上个月还剩余天数未渲染
                str += "<td style='color:#989898;'>" + start + "</td>" ; //渲染上个月的剩余天数,并置为灰色
                start++;
            }else if(curIndex > days || flag == true){ //当月天数渲染完之后,剩余的位置用于渲染下个月的天数
                flag == true;
                str += "<td style='color:#989898;'>" + (curIndex - days) + "</td>" ;
                curIndex++;
            }else{ //渲染当月的天数
                str += "<td>" + curIndex + "</td>" ;
                curIndex++;
            }
        }
        str += "</tr>";
    } 
    str += "</table>"
    calBox.innerHTML = str;
}

为两个按钮添加事件委托:

	setNewDate(); // 初始化日期
	calendar.addEventListener("click",function(e){ //为两个按钮设置事件委托
	    if(e.target.id == "calendar-pre"){ //当点击上一个月的按钮时
	        month = preMonth;
	        preMonth = month - 1;
	        nextMonth = month + 1;
	        if(month == 12){ //边界值判断
	            year--;
	        }
	        setNewDate(); //更新日期
	    }
	    if(e.target.id == "calendar-next"){ //当点击下一个月的按钮时
	        month = nextMonth;
	        preMonth = month - 1;
	        nextMonth = month + 1;
	        if(month == 1){ //边界值判断
	            year++;
	        }
	        setNewDate(); //更新日期
	    }
	});

由于两个按钮是后面通过js进行添加的,所以无法对其直接进行事件的监听,需要对其父元素设置事件监听。
这里我还为日历设置了定制功能,例如上述实现的是从周一开始的日历,要设置成周日开始的日历,只需要修改参数即可:

	var weeks = ['日','一','二','三','四','五','六'];//设置头部是从周一开始还是周日开始

在setNewDate()方法中:

	begin = predays - whatday + 1; // 设置上一个月还剩几天的天数显示
    getCalendar(weeks, begin, whatday); //传入参数,调用getCalender方法

这样子就可以实现以周日为开始的日历了:
请添加图片描述
这次的小插件虽然实现起来不是特别的复杂,但是还是涉及到了比较多的知识,最主要的就是对日期对象的操作,这次的小demo就介绍到这里啦,有不足的地方也希望大家可以帮我指正,蟹蟹!


版权声明:本文为weixin_43866830原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。