日历组件带农历及事件标记,绑定点击事件

前段时间需要做一个课程日历的记事,还需要带农历,网上查了一下现有的日历带农历的代码分享,整合了一下自己的事件业务逻辑,最终做了这么一个日历组件(农历使用紫金山天文台农历编码1921-2023,有没有大神补充,2023年的编码也在润2月之后对不上了[//emo],找了很久没找到做资料)

CalendarData : new Array(
      0xA4B, 0x5164B, 0x6A5, 0x6D4, 0x415B5, 0x2B6, 0x957, 0x2092F, 0x497, 0x60C96, 0xD4A, 0xEA5,
      0x50DA9, 0x5AD, 0x2B6, 0x3126E, 0x92E, 0x7192D, 0xC95, 0xD4A, 0x61B4A, 0xB55, 0x56A, 0x4155B, 0x25D, 0x92D, 0x2192B,
      0xA95, 0x71695, 0x6CA, 0xB55, 0x50AB5, 0x4DA, 0xA5B, 0x30A57, 0x52B, 0x8152A, 0xE95, 0x6AA, 0x615AA, 0xAB5, 0x4B6,
      0x414AE, 0xA57, 0x526, 0x31D26, 0xD95, 0x70B55, 0x56A, 0x96D, 0x5095D, 0x4AD, 0xA4D, 0x41A4D, 0xD25, 0x81AA5, 0xB54,
      0xB6A, 0x612DA, 0x95B, 0x49B, 0x41497, 0xA4B, 0xA164B, 0x6A5, 0x6D4, 0x615B4, 0xAB6, 0x957, 0x5092F, 0x497, 0x64B,
      0x30D4A, 0xEA5, 0x80D65, 0x5AC, 0xAB6, 0x5126D, 0x92E, 0xC96, 0x41A95, 0xD4A, 0xDA5, 0x20B55, 0x56A, 0x7155B, 0x25D,
      0x92D, 0x5192B, 0xA95, 0xB4A, 0x416AA, 0xAD5, 0x90AB5, 0x4BA, 0xA5B, 0x60A57, 0x52B, 0xA93, 0x40E95, 0x6aa, 0xad5
  )

话不多说,先上效果图:

 

 实现代码:

/*日历控件*/
var CalendarModal = {
    createCalendar:function(params) {
        //创建节点
        var str = '<table width="100%" border="0" cellpadding="0" cellspacing="0" style="text-align: center">'+
            '<th class="calendar-head" colspan="7">'+
            '<span id="showLastMonth" class="monthBtn"><</span>'+
            '<span id="showYear">2023</span>年<span id="showMonth"></span>月'+
            '<span id="showNextMonth" class="monthBtn">></span>'+
            '</th>'+
            '<tr class="calendar-week">'+
            '<td>日</td><td>一</td><td>二</td><td>三</td><td>四</td><td>五</td><td>六</td>'+
            '</tr>'+
            '</table>'+
            '<div id="showDay"></div>'

        var domId = params.id?params.id:'calendar_panl';
        var callFun = params.callback
        $("#"+domId).append(str)
        //获取当前日期
        var date = new Date();
        var year = date.getFullYear();//年
        var month = date.getMonth();//月(0-11)
        var lastBtn = document.getElementById("showLastMonth");//左侧按钮
        var nextBtn = document.getElementById("showNextMonth");//右侧按钮
        lastBtn.onclick = function () {
            if (month == 0) {
                year -= 1;
                month = 11;
            } else {
                month--;
            }
            CalendarModal.showDate(new Date(year, month, 1));
            try {
                callFun();
            } catch (error) {

            }
        }
        nextBtn.onclick = function () {
            if (month == 11) {
                year += 1;
                month = 0;
            } else {
                month++;
            }
            CalendarModal.showDate(new Date(year, month, 1));
            try {
                callFun();
            } catch (error) {

            }
        }
        CalendarModal.showDate(new Date(year, month, 1));
        try {
            callFun();
        } catch (error) {

        }
    },
//日历生成

    showDate:function(obj){
        var year = obj.getFullYear();//年
        var month = obj.getMonth();//月
        var date = new Date();
        var currentY = date.getFullYear();//年
        var currentM = date.getMonth();//月(0-11)
        var currentD = date.getDate();//日
        var sDay = new Date(year,month,1).getDay();//本月第一天星期几
        var days = new Date(year,month+1,0).getDate();//本月一共多少天
        document.getElementById("showYear").innerHTML = year;
        document.getElementById("showMonth").innerHTML = month+1;
        var dayObj = document.getElementById("showDay");
        var htmlStr = "";
        for(var i = 0;i<sDay;i++){
            htmlStr +='<div class="dayItemNoNum"></div>'
        }
        for (var i = 1; i <= days; i++) {
            var char = CalendarModal.showCal(new Date(year,month,i));
            var courseMark = 'course_mark_' + i; // 课程提醒标记ID
            var notesMark = 'notes_mark_' + i; // 备忘提醒标记ID
            var workMark = 'work_mark_' + i //任务信息标记ID
            if(currentY==year&&currentM==month&&currentD==i){
                htmlStr += '<div class="dayItemNum"><div class="dayItem dayItemMark calendarActive"><span>'+i+'</span><br><span class="calendarNum">'+char+'</span><div class="calendarMark_div">'+
                    '<div class="calendarMark_red" style="display:none;" id=' + courseMark + '></div>'+
                    '<div class="calendarMark_yellow" style="display:none;" id=' + notesMark + '></div>'+
                    '<div class="calendarMark_pink" style="display:none;" id=' + workMark + '></div></div></div></div>';
            }else{
                htmlStr += '<div class="dayItemNum"><div class="dayItem"><span>'+i+'</span><br><span class="calendarNum">'+char+'</span><div class="calendarMark_div">'+
                    '<div class="calendarMark_red" style="display:none;" id=' + courseMark + '></div>'+
                    '<div class="calendarMark_yellow" style="display:none;" id=' + notesMark + '></div>'+
                    '<div class="calendarMark_pink" style="display:none;" id=' + workMark + '></div></div></div></div>';
            }
        }
        dayObj.innerHTML = htmlStr;
        CalendarModal.addCalendarClick();
    },

    //添加日历点击事件
    addCalendarClick:function(){
        //点击事件(可重写)
        var doms = $('.dayItem');
        for(var i = 0;i<doms.length;i++){
            doms[i].onclick = function(){
                for(var j = 0;j<doms.length;j++){
                    $(doms[j]).removeClass('calendarActive');
                }
                $(this).addClass('calendarActive');
            }
        }
    },

    //农历计算
    showCal:function(obj) {
        var yy = obj.getFullYear()
        var mm = obj.getMonth() + 1
        var dd = obj.getDate()
        if (yy < 100) yy = '19' + yy
        return CalendarModal.GetLunarDay(yy, mm, dd)
    },

    //定义变量
    CalendarData : new Array(100),
    madd : new Array(12),
    tgString : '甲乙丙丁戊己庚辛壬癸',
    dzString : '子丑寅卯辰巳午未申酉戌亥',
    numString : '一二三四五六七八九十',
    monString : '正二三四五六七八九十冬腊',
    weekString : '一二三四五六日',
    sx : '鼠牛虎兔龙蛇马羊猴鸡狗猪',
    cYear:'',
    cMonth:'',
    cDay:'',
    TheDate:'',
    CalendarData : new Array(
        0xA4B, 0x5164B, 0x6A5, 0x6D4, 0x415B5, 0x2B6, 0x957, 0x2092F, 0x497, 0x60C96, 0xD4A, 0xEA5,
        0x50DA9, 0x5AD, 0x2B6, 0x3126E, 0x92E, 0x7192D, 0xC95, 0xD4A, 0x61B4A, 0xB55, 0x56A, 0x4155B, 0x25D, 0x92D, 0x2192B,
        0xA95, 0x71695, 0x6CA, 0xB55, 0x50AB5, 0x4DA, 0xA5B, 0x30A57, 0x52B, 0x8152A, 0xE95, 0x6AA, 0x615AA, 0xAB5, 0x4B6,
        0x414AE, 0xA57, 0x526, 0x31D26, 0xD95, 0x70B55, 0x56A, 0x96D, 0x5095D, 0x4AD, 0xA4D, 0x41A4D, 0xD25, 0x81AA5, 0xB54,
        0xB6A, 0x612DA, 0x95B, 0x49B, 0x41497, 0xA4B, 0xA164B, 0x6A5, 0x6D4, 0x615B4, 0xAB6, 0x957, 0x5092F, 0x497, 0x64B,
        0x30D4A, 0xEA5, 0x80D65, 0x5AC, 0xAB6, 0x5126D, 0x92E, 0xC96, 0x41A95, 0xD4A, 0xDA5, 0x20B55, 0x56A, 0x7155B, 0x25D,
        0x92D, 0x5192B, 0xA95, 0xB4A, 0x416AA, 0xAD5, 0x90AB5, 0x4BA, 0xA5B, 0x60A57, 0x52B, 0xA93, 0x40E95, 0x6aa, 0xad5
    ),
    madd:new Array(0,31,59,90,120,151,181,212,243,273,304,334),

    GetBit:function(m, n) {
        return (m >> n) & 1
    },
    //农历转换
    e2c:function() {
        TheDate =
            arguments.length != 3
                ? new Date()
                : new Date(arguments[0], arguments[1], arguments[2])
        var total, m, n, k
        var isEnd = false
        var tmp = TheDate.getYear()
        if (tmp < 1900) {
            tmp += 1900
        }
        total =
            (tmp - 1921) * 365 +
            Math.floor((tmp - 1921) / 4) +
            CalendarModal.madd[TheDate.getMonth()] +
            TheDate.getDate() -
            38

        if (TheDate.getYear() % 4 == 0 && TheDate.getMonth() > 1) {
            total++
        }
        for (m = 0; ; m++) {
            k = CalendarModal.CalendarData[m] < 0xfff ? 11 : 12
            for (n = k; n >= 0; n--) {
                if (total <= 29 + CalendarModal.GetBit(CalendarModal.CalendarData[m], n)) {
                    isEnd = true
                    break
                }
                total = total - 29 - CalendarModal.GetBit(CalendarModal.CalendarData[m], n)
            }
            if (isEnd) break
        }
        CalendarModal.cYear = 1921 + m
        CalendarModal.cMonth = k - n + 1
        CalendarModal.cDay = total
        if (k == 12) {
            if (CalendarModal.cMonth == Math.floor(CalendarModal.CalendarData[m] / 0x10000) + 1) {
                CalendarModal.cMonth = 1 - CalendarModal.cMonth
            }
            if (CalendarModal.cMonth > Math.floor(CalendarModal.CalendarData[m] / 0x10000) + 1) {
                CalendarModal.cMonth--
            }
        }
    },

    GetcDateString:function() {
        var tmp = ''
        tmp += CalendarModal.cDay < 11 ? '初' : CalendarModal.cDay < 20 ? '十' : CalendarModal.cDay < 30 ? '廿' : '三十'
        if (CalendarModal.cDay % 10 != 0 || CalendarModal.cDay == 10) {
            tmp += CalendarModal.numString.charAt((CalendarModal.cDay - 1) % 10)
        }
        return tmp
    },

    GetLunarDay:function(solarYear, solarMonth, solarDay) {
        if (solarYear < 1921 || solarYear > 2025) {
            return "";
        } else {
            solarMonth = (parseInt(solarMonth) > 0) ? (solarMonth - 1) : 11;
            CalendarModal.e2c(solarYear, solarMonth, solarDay);
            return CalendarModal.GetcDateString();
        }
    }
}

css样式:(自己瞎写的风格,有需要可以自己改动哈,本来想加个换肤功能,业务太忙就没再写了,提供下思路:设置主题class 类似skin_pink【粉色】等,切换的时候替换掉这个父类的class)

/*日历*/
.calendar-head{
    text-align: center;
    font-size: 16px;
    font-weight: bold;
    line-height: 30px;
    background-color: #fe8e4a !important;
    border-top-right-radius: 5px;
    border-top-left-radius: 5px;
    color: #fff;
}
.calendar-week{
    background-color: #fea26a;
    text-align: center;
    color: #fff;
    line-height: 25px;
}
#showDay{
    height: 210px;
}
.dayItemNum,.dayItemNoNum{
    width: 14.285%;
    float: left;
    margin-top: 2px;
}
.dayItem{
    margin: 0 auto;
    height: 35px;
    width: 38px;
    border-radius: 21px;
    line-height: 15px;
    text-align: center;
    cursor: pointer;
    font-size: 17px;
    padding-top: 3px;
    /*font-weight: bold;*/
    position: relative;
    border: 2px solid #fff;;
}
.dayItemMark{
    background-color: #fddcdc;
}
.dayItem:hover{
    border: 2px solid #f45151;
    box-shadow:0px 5px 10px rgba(0,0,0,0.3);
}
.calendarActive{
    border: 2px solid #f45151;
    box-shadow:0px 5px 10px rgba(0,0,0,0.3);
}
.monthBtn{
    cursor: pointer;
    background-color: #e3691e;
    padding-left: 3px;
    padding-right: 3px;
    border-radius: 12px;
    line-height: 16px;
    display: inline-block;
    font-size: 14px;
    color: #fff;
}
.calendarNum{
    font-size: 12px;
    font-weight: normal;
    color: #999;
}
.calendarMark_red{
    background-color: #f45151;
    height: 5px;
    width: 5px;
    border-radius: 4px;
    margin-left: 2px;
    float: left;
}
.calendarMark_yellow{
    background-color: #ffc000;
    height: 5px;
    width: 5px;
    border-radius: 4px;
    margin-left: 2px;
    float: left;
}
.calendarMark_pink{
    background-color: #037ff5f0;
    height: 5px;
    width: 5px;
    border-radius: 4px;
    float: left;
    margin-left: 2px;
}
.calendarMark_div{
    position: absolute;
    height: 10px;
    width: 21px;
    right: -10px;
    top: 4px;
}
/*日历end*/

调用代码:(原本点击功能绑定了弹窗,我给摘除了,需要的可以加上,推荐使用layer弹窗,推荐原因是因为自己用的多[//汗])

$(function(){
        CalendarModal.createCalendar({id:'calendar_panl',callback:function(){
          //举例几号有备注,此处可发起请求,回调标注
          $('#work_mark_'+10).css('display','block')
          $('#notes_mark_'+10).css('display','block')
          $('#course_mark_'+10).css('display','block')
          $('#work_mark_'+8).css('display','block')
          $('#notes_mark_'+8).css('display','block')
          $('#course_mark_'+8).css('display','block')
          $('#work_mark_'+9).css('display','block')
          $('#notes_mark_'+7).css('display','block')
          $('#course_mark_'+7).css('display','block')
          $('#work_mark_'+3).css('display','block')
          $('#notes_mark_'+3).css('display','block')
          $('#course_mark_'+4).css('display','block')
          $('#work_mark_'+13).css('display','block')
          $('#notes_mark_'+13).css('display','block')
          $('#course_mark_'+13).css('display','block')
          $('#work_mark_'+16).css('display','block')
          $('#notes_mark_'+16).css('display','block')
          $('#course_mark_'+17).css('display','block')
        }}); 
    })

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在Flutter中,您可以使用`TableCalendar`库来创建一个日历,并在日期下方设置事件标记点。以下是一种实现方式: 1. 首先,确保您已经安装了`table_calendar`库。在`pubspec.yaml`文件中添加以下依赖项: ```yaml dependencies: table_calendar: ^2.3.3 ``` 然后运行`flutter pub get`来获取最新的依赖项。 2. 导入所需的库: ```dart import 'package:table_calendar/table_calendar.dart'; ``` 3. 创建一个`TableCalendar`小部件并设置相关属性,例如: ```dart TableCalendar( // 设置日历的起始和结束日期 firstDay: DateTime.utc(2022, 1, 1), lastDay: DateTime.utc(2022, 12, 31), // 设置事件标记的日期列表 eventLoader: (day) { // 返回包含事件的日期列表 // 如果某一天有事件,则返回该日期,否则返回null List<String> events = getEventsForDay(day); return events.isNotEmpty ? events : null; }, // 自定义事件标记的样式 calendarStyle: CalendarStyle( markersColor: Colors.blue, markersAlignment: Alignment.bottomCenter, markersPositionBottom: 0, ), ) ``` 在上述代码中,您可以通过设置 `firstDay` 和 `lastDay` 属性来指定日历的起始和结束日期。通过 `eventLoader` 属性,您可以返回包含事件的日期列表,以便在日历中进行标记。 4. 在您的`getEventsForDay`函数中,根据日期加载对应的事件列表。例如: ```dart List<String> getEventsForDay(DateTime day) { // 根据日期加载事件列表 // 返回包含事件的日期列表 // 如果某一天有事件,则返回该日期,否则返回空列表 if (day == DateTime.utc(2022, 1, 1)) { return ['Event 1', 'Event 2']; } else if (day == DateTime.utc(2022, 1, 5)) { return ['Event 3']; } return []; } ``` 在上述代码中,您可以根据具体的日期返回相应的事件列表。 通过以上步骤,您可以在`TableCalendar`日历中的日期下方设置事件标记点。请根据您的需求自定义事件标记的样式和事件加载逻辑。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

格乌恩

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值