{"id":19545156,"url":"https://github.com/scscms/scs-calendar","last_synced_at":"2026-01-28T13:34:07.997Z","repository":{"id":93555079,"uuid":"70794728","full_name":"scscms/scs-calendar","owner":"scscms","description":"ES6 编写基本的日历控制","archived":false,"fork":false,"pushed_at":"2016-10-19T08:36:46.000Z","size":45,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-06T02:41:22.383Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scscms.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-10-13T10:16:20.000Z","updated_at":"2018-06-26T07:32:00.000Z","dependencies_parsed_at":"2023-10-02T08:03:49.975Z","dependency_job_id":null,"html_url":"https://github.com/scscms/scs-calendar","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/scscms/scs-calendar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scscms%2Fscs-calendar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scscms%2Fscs-calendar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scscms%2Fscs-calendar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scscms%2Fscs-calendar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scscms","download_url":"https://codeload.github.com/scscms/scs-calendar/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scscms%2Fscs-calendar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28846052,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T13:02:32.985Z","status":"ssl_error","status_checked_at":"2026-01-28T13:02:04.945Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T03:35:42.927Z","updated_at":"2026-01-28T13:34:07.981Z","avatar_url":"https://github.com/scscms.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ES2015　日历控件\u003csup\u003eshine\u003c/sup\u003e\n\n很久以前就想自己写个日历控件，可以应付设计师的特殊界面。\n网上也很多日期选择控件，而且功能强大丰富。原代码也及其复杂难懂，其实日历可以更加简单实现，虽然在此使用的是ES2015，直接转成ES5也是可以的。\n\n### 界面分析\n\n如图：\n\n![image](https://github.com/scscms/scs-calendar/raw/master/calendar.jpg)\n\n可看到，每个月的日历界面由上个月末尾几天，和本月所有天数加上下个月的月初几天组成，共7 X 6 = 42个格子。\n主要难题其实就只有一个：获取某个月最后一天的号数是多少？网上大部分做法就是判断是否闰年是否是闰月等去取。\n其实我们有一个更简单的方法：把某个日期对象的天数设置成0，它会自动转换成该日期的上个月最后一天的日期。\n```javascript\nvar ymd = new Date(2016,2,0);//自动获取到2016年2月最后一天日期\nconsole.log(ymd);// Date {Mon Feb 29 2016 00:00:00 GMT+0800}\n```\n\n### 1.初级界面\n首先我们只显示当前月份的日期来实现一个简单界面：\n```javascript\n\t\"use strict\";\n    const nowDate = new Date();//当前日期\n    const nowYear = nowDate.getFullYear();//当前日期的年份\n    const nowMonth = nowDate.getMonth() + 1;//当前日期的月分\n    const firstDay = new Date(nowYear,nowMonth - 1,1);//当前日期的第一天日期\n    const lastDay = new Date(nowYear,nowMonth,0).getDate();//获取本月最后一天的号数\n    const arrayDay = [];//当前日历的日期数组;\n    for(let i = 1;i \u003c= lastDay;i ++){\n        arrayDay.push(nowYear + \"-\"+ nowMonth + \"-\"+ i);\n    }\n\n    let firstWeek = firstDay.getDay();//当前日期的第一天的星期\n    if(firstWeek \u003e 0){\n        //假如第一天不是从星期天开始，需要补充日期数组\n        for(let i = firstWeek;i --;)arrayDay.unshift(\"\");\n    }\n    //日期数组大部分都不够长，再加下个月的14天空位\n    for(let i = 14;i--;)arrayDay.push(\"\");\n\n    let table = `\u003ctable border=\"0\" cellpadding=\"5\" cellspacing=\"0\"\u003e\u003ctr\u003e\u003ctd\u003e日\u003c/td\u003e\n    \u003ctd\u003e一\u003c/td\u003e\u003ctd\u003e二\u003c/td\u003e\u003ctd\u003e三\u003c/td\u003e\u003ctd\u003e四\u003c/td\u003e\u003ctd\u003e五\u003c/td\u003e\u003ctd\u003e六\u003c/td\u003e\u003c/tr\u003e\u003ctbody\u003e`;\n    //遍历组成一个7 X 6的日历界面\n    for(let l = 0;l \u003c= 42;l ++){\n        if(l % 7 == 0){\n            table += `\u003ctr\u003e`;\n        }\n        //截取相应日期显示\n        table += `\u003ctd\u003e${arrayDay[l].replace(/\\d+\\-/g,\"\")}\u003c/td\u003e`;\n        if(l + 1 % 7 == 0){\n            table += `\u003c/tr\u003e`;\n        }\n    }\n    table += `\u003c/tbody\u003e\u003c/table\u003e`;\n\n    document.querySelector(\".scs_calendar\").innerHTML = table;\n```\n[查看完整代码](index.html)\n\n### 2.添加年月select选择\n\n[查看完整代码](index2.html)\n\n当然这是凭直觉直接写出来的代码。其中我们仍有优化的空间：比如年月select可只执行一次innerHTML；甚至table td也可一次性生成，后继修改其文本或样式即可；\n最后还没增加点击日期事件哟。\n\n### 3.经过优化的代码\n\n思路是先使用js生成整体html然后根据传入的年份和月份修改相应的日期即可。同时使用事件委托监听点击事件。\n这样改变年月时调用的函数就很简洁了：\n```javascript\n    function scsCalendar(year,month){\n        const firstDay = new Date(year,month - 1,1);//当前日期的第一天日期\n        const lastDay = new Date(year,month,0).getDate();//获取本月最后一天的号数\n        let firstWeek = firstDay.getDay();//当前日期的第一天的星期\n        for(let i = 0;i \u003c 42;i ++){\n            let td = dateObj.tds[i],day = i \u003e= firstWeek \u0026\u0026 i \u003c lastDay + firstWeek ? i - firstWeek + 1 : \"\";\n            td.innerHTML = day;//dateObj.tds.textContent\n            td.setAttribute(\"data-ymd\",day ? year + \"-\" + month + \"-\" + (\"0\" + day).slice(-2) :\"\");\n        }\n        dateObj.selectDom[0].value = year;\n        dateObj.selectDom[1].value = month;\n    }\n```\n[查看完整代码](index3.html)\n\n### 4.按UI制作日期选择器\n如图：\n![image](https://github.com/scscms/scs-calendar/raw/master/ymd.jpg)\n这是设计师给的UI给我，可见切换月份是使用左右箭头。但是如果切换年份就尴尬了，要切换12个月才换一年呀。其实可以点击年月进入选择年份的界面。\n而且注意，当月界面同时会显示前后两个月的部分日期。已经没有了关闭按钮，表示点击日历外自动关闭。\n[查看完整代码](index4.html) underway...\n### 5.编写成jQuery插件\n下一站...\n\n### 6.日历的简单限制\n下二站...","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscscms%2Fscs-calendar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscscms%2Fscs-calendar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscscms%2Fscs-calendar/lists"}