原生js实现日历

本文介绍了一个基于Vue.js实现的日历组件,详细展示了HTML、CSS和JavaScript代码,并提供了丰富的注释帮助理解。组件具备切换月份的功能,同时能够展示特定日期的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hey,bro! 为了让这个看起来正式一点,小白的第一次记录要认真好好的写。

重大说明
实习期间,觉得大多学习的东西需要好好记录一下,今天,在这个重大的日子里,我终于动手了。此文章背景来源于同事之前写的一个,我自己做了一下整理,觉得在很多时候都可以用到。

上一波效果图:
在这里插入图片描述
话不多说贴代码

// html
<div id="app">
    <div class="up">
        <div class="calendar">
            <div id="schedule-box" class="boxshaw"></div>
        </div>
        <div class="weekclass" v-for="item in weekalllist" :class="{'checkit': item.weekday == checkday, 'week-box' : item.weekday != checkday}">
            <div class="weekday">
                <div class="day" v-text="item.day"></div>
                <div class="week" v-text="item.week"></div>
            </div>
        </div>
    </div>
</div>
// css
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        ul{
            list-style: none;
        }
        .up{
            width:80%;
            height:500px;
            border: 1px solid #333;
            padding-bottom: 30px;
            min-height:380px;
            margin:100px auto;
        }
        .calendar{
            position: relative;
            width:300px;
            height:100%;
            display: inline-block;
        }
        .boxshaw{
            width:100%;
            font-size:13px;
            position: absolute;
            display: inline-block;
            top:50%;
            left:50%;
            transform:translate(-50%,-50%);
        }
        .schedule-hd{
            display: flex;
            justify-content: space-between;
            padding:0 15px;
        }
        .today{
            flex:1;
            text-align:center;
        }
        .ul-box{
            overflow: hidden;
        }
        .ul-box >li{
            float:left;
            width:14.28%;
            text-align: center;
            padding:5px 0;
        }
        .other-month{
            color:#999999;
        }
        .current-month {
            color: #333333;
        }
        .dayStyle{
            width:35px;
            height:35px;
            border-radius: 50%;
            text-align: center;
            line-height: 35px;
            display: inline-block;
            cursor: pointer;
        }
        .current-month > .dayStyle:hover{
            background: rgb(153,153,153);
            color:#ffffff;
        }
        .today-flag{
            background:pink;
            color:#ffffff;
        }
        .iconfonts {
            font-family: "iconfont" !important;
            font-size: 20px;
            font-style: normal;
            -webkit-font-smoothing: antialiased;
        }
        .arrow {
            cursor: pointer;
        }
        .weekclass{
            width:calc((100% - 315px)/7);
            height:100%;
            display: inline-block;
            padding-top:30px;
            vertical-align: top;
            border-left:1px solid #cccccc;
            cursor:pointer;
        }
        .weekday{
            height:60px;
            width:100%;
        }
        .weekday .day {
            font-size: 22px;
            height: 22px;
            line-height: 22px;
            width: 100%;
            text-align: center;
            color: #999999;
        }
        .weekday .week {
            font-size: 22px;
            width: 100%;
            height: 22px;
            line-height: 22px;
            text-align: center;
            color: #999999;
        }
        .checkit{
            position:relative;
        }
        .checkit::after{
            position: absolute;
            content:"";
            top:0px;
            width:100%;
            height:0px;
            border-top:8px solid pink;
            display: block;
        }
        .week-box{
            position: relative;
        }
        .week-box:hover::after{
            display:block;
        }
        .week-box::after{
            position: absolute;
            content:"";
            top:0px;
            width:100%;
            height:0px;
            border-top:8px solid pink;
            display: none;
        }
    </style>
//js
<script>
    //日期格式化
    window.year = new Date().getFullYear();
    window.month = new Date().getMonth();
    window.selectedDate = '';
    window.day = new Date().getDate();

    //转换日期格式:y-m-d
    function formartDate (y,m,d,symbol) {
        symbol = symbol || '-';
        m = (m.toString())[1] ? m : '0'+m;
        d = (d.toString())[1] ? d : '0'+d;
        return y+symbol+m+symbol+d
    };
    //转换month格式
    function formartmonth (y,m,symbol) {
        symbol = symbol || '-';
        m = (m.toString())[1] ? m : '0'+m;
        return y+symbol+m
    };
    function Schedule(e,optdate) {
        var curDate = new Date(),
            currentYear = curDate.getFullYear(),
            currentMonth = curDate.getMonth(),
            currentDay = curDate.getDate(),
            el = document.querySelector(e) || document.querySelector('body');
        if(optdate.length) {
            for(var i = 0;i<optdate.length;i++) {
                optdate[i] = new Date(optdate[i]);

            }
        }else {
            optdate = [];
        }
        var init = function () {
            var scheduleHd = '<div class="schedule-hd">'+
                '<div>' +
                '<span class="arrow iconfonts icon-jiantouyou" id="prevMonth"></span>' +
                '</div>' +
                '<div class="today">'+ formartmonth(year,month+1,'-') + '</div>' +
                '<div>' +
                '<span class="arrow iconfonts icon-jiantouzuo" id="nextMonth"></span>' +
                '</div>' +
                '</div>'
            var scheduleWeek = '<ul class="week-ul ul-box">' +
                '<li>日</li>' +
                '<li>一</li>' +
                '<li>二</li>' +
                '<li>三</li>' +
                '<li>四</li>' +
                '<li>五</li>' +
                '<li>六</li>' +
                '</ul>'
            var scheduleBd = '<ul class="schedule-bd ul-box"></ul>';
            el.innerHTML = scheduleHd + scheduleWeek + scheduleBd;
            render();
        }
        var render = function () {
            var fullDay = new Date(year,month+1,0).getDate(), //当月总天数
                startWeek = new Date(year,month,1).getDay(), //当月第一天是周几
                total = (fullDay+startWeek)%7 == 0 ? (fullDay+startWeek) : fullDay+startWeek+(7-(fullDay+startWeek)%7),//元素总个数
                lastMonthDay = new Date(year,month,0).getDate(), //上月最后一天
                eleTemp = [];
            for(var i = 0; i < total; i++){
                if(i<startWeek){
                    eleTemp.push('<li class="other-month"><span class="dayStyle">'+(lastMonthDay-startWeek+1+i)+'</span></li>')
                }else if(i<(startWeek+fullDay)){
                    var nowDate = formartDate(year,month+1,(i+1-startWeek),'-');

                    var addClass = '';
                    for(var j = 0;j<optdate.length;j++) {
                        var kyear = optdate[j].getFullYear(),
                            kmonth = optdate[j].getMonth(),
                            kday = optdate[j].getDate();
                        var keyday = formartDate(kyear,kmonth+1,kday,'-');
                        if(nowDate == keyday) {
                            addClass = 'huiyi-flag';
                        }
                    }

                    selectedDate == nowDate && (addClass = 'selected-style');
                    formartDate(currentYear,currentMonth+1,currentDay,'-') == nowDate && (addClass = 'today-flag');
                    eleTemp.push('<li class="current-month" ><span title='+nowDate+' class="currentDate dayStyle '+addClass+'">'+(i+1-startWeek)+'</span></li>')
                }else{

                    eleTemp.push('<li class="other-month"><span class="dayStyle">'+(i+1-(startWeek+fullDay))+'</span></li>')
                }
            }
            el.querySelector('.schedule-bd').innerHTML = eleTemp.join('');
            el.querySelector('.today').innerHTML = formartmonth(year,month+1,'-');
        };
        init();
    }
    //对Date的扩展,将Date转化为指定格式的String
    Date.prototype.format = function(format) {
        var date = {
            "M+": this.getMonth() + 1, //月份
            "d+": this.getDate(), //日
            "h+": this.getHours(), //小时
            "m+": this.getMinutes(), //分
            "s+": this.getSeconds(), //秒
            "q+": Math.floor((this.getMonth() + 3) / 3), //季度
            "S+": this.getMilliseconds()  //毫秒
        };
        if (/(y+)/i.test(format)) {
            format = format.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
        }
        for (var k in date) {
            if (new RegExp("(" + k + ")").test(format)) {
                format = format.replace(RegExp.$1, RegExp.$1.length == 1
                    ? date[k] : ("00" + date[k]).substr(("" + date[k]).length));
            }
        }
        return format;
    }
    !function () {
        initVue();
    }();
    function initVue() {
        var _app = new Vue({
            el:"#app",
            data(){
                return{
                    nowd:'',
                    nowm:'',
                    nowy:'',
                    datelist:[],
                    weekalllist:[],
                    checkday:'',
                }
            },
            mounted(){
                let that = this;
                var date = new Date();
                var year = date.getFullYear();
                var month = date.getMonth()+1;
                var day = date.getDate();
                that.showweek(year,month,day);
                if(month < 10) {
                    month = "0"+month;
                }
                if(day < 10) {
                    day = "0"+day;
                }
                that.initcalendar();
            },
            methods:{
                initcalendar() {
                    var that = this;

                    Schedule('#schedule-box',that.datelist);
                    $("#schedule-box").on('click',function(e){
                        if(e.target.id == 'nextMonth') {

                            if(month+1 > 11){
                                year += 1;
                                month = 0;
                            }else{
                                month += 1;
                            }
                            that.uploadtable(year,month+1,day);
                        }
                        if(e.target.id == 'prevMonth') {
                            if(month-1 < 0){
                                year -= 1;
                                month = 11;
                            }else{
                                month -= 1;
                            }
                            that.uploadtable(year,month+1,day);
                        }
                        if(e.target.className.indexOf('currentDate') > -1){
                            selectedDate = e.target.title;

                            Schedule('#schedule-box',that.datelist);
                            that.showweek(year,month+1,e.target.innerHTML);
                        }
                    })
                },
                uploadtable(y,m,d){
                    let that = this;
                    that.datelist = [];
                    Schedule('#schedule-box',that.datelist);
                },
                //左侧日历完成到这里*********
                showweek(y,m,d){
                    let that = this;
                    if(d < 10){
                        d = "0" + d;
                    }
                    if(m < 10){
                        m = "0" + m;
                    }
                    var time = y + '-' + m + '-' + d;
                    this.checkday = time;
                    var k = new Date(time);
                    var day = k.getDay() || 7;//获取当前星期X(0-6,0周日)

                    var startTime = new Date(k.getFullYear(), k.getMonth(), k.getDate() + 1 - day);
                    var endTime = new Date(k.getFullYear(), k.getMonth(), k.getDate() + (7 - day));

                    that.weekdata(startTime,endTime);
                },
                weekdata(startTime,endTime){
                    let that = this;
                    that.weekalllist = [];
                    while((endTime.getTime()-startTime.getTime())>=0){
                        var year = startTime.getFullYear();
                        var month = startTime.format("MM");
                        var day = startTime.format("dd");
                        var isday = year+"-"+month+"-"+day;

                        var n = new Date(isday).getDay(); //startTime的星期X
                        var base = {
                            day:day,
                            week:that.getweek(n), //0为周日6为周六
                            weekday:isday,
                            data:[],
                        };
                        that.weekalllist.push(base);

                        startTime.setDate(startTime.getDate()+1);
                    }
                    that.weekalllist.forEach((val,index) => {
                        val.data.sort(function(a,b){
                            return Date.parse(a.start) - Date.parse(b.start);
                        });
                    })
                },
                getweek(val){
                    var week;
                    switch(val)  {
                        case 0:
                            week = "周日";
                            break;
                        case 1:
                            week = "周一";
                            break;
                        case 2:
                            week = "周二";
                            break;
                        case 3:
                            week = "周三";
                            break;
                        case 4:
                            week = "周四";
                            break;
                        case 5:
                            week = "周五";
                            break;
                        case 6:
                            week = "周六";
                            break;
                    }
                    return week;
                }
            }
        })
    }
</script>

代码量有点多,不过是可以拿来用的,不要忘记了引入jquery.js以及vue.js。至于icon,我是用的阿里的图标矢量库,外部引入的。不过后来他们推荐的vue-calendar-componen是基于vue2.0开发的轻量级组件,咦,也是原生js开发,我没仔细看,但我估计差不多,因为同事原来也是从网上找的,但是我没有去找来源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值