打卡日历
参考地址
https://blog.csdn.net/weixin_42283981/article/details/87976273
在此基础上做了修改
思路
在日历对象中,确认当前月的天数:找到本月的第一天和下个月的第一天
- html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="css/reset.css">
<link href="css/card.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="warp" class="wrap_card">
<div class="card_title">
<h4><i class="title_pic"></i>考勤详情</h4>
</div>
<div class="handler_line">
<div class="handler_month">
月
<span class="b_line"></span>
</div>
<div class="date_show">
<div class="pre_month">
<i></i>
</div>
<div class="cur_month"></div>
<div class="nxt_month">
<i></i>
</div>
</div>
</div>
<div id="card">
</div>
</div>
<!-- <script src="copy.js"></script> -->
<script src="copy2.js"></script>
</body>
</html>
- js
function Calend(id1,id2,fn) {
//
var $content;
var $body;
var $data; //当前日期
var $month;//当前月份
var $year;//当前年份
var $curDay;//当前月中的当前天
var $model_arr ;
var $wrap
const that = this;
this.init = function (year, month) {
// 获取承载日历的父元素
this.setparentNode()
$content.innerHTML = ''
if (year && (month||month==0)) {
this.setDate_now(year, month)
} else {
this.setDate_now()
}
this.formatter_arr(fn)
// 添加日期
fill_in_date()
// 设置日历头部
addHead();
addBody()
}
this.setparentNode = function () {
if (document.getElementById(id1)) {
$wrap = document.getElementById(id1);
$content = document.getElementById(id2);
} else {
alert('查找不到该元素')
}
}
this.setDate_now = function (year, month) {
if (year && (month||month==0)) {
$data = new Date(year, month, $curDay);
} else {
$data = new Date();
}
$curDay = $data.getDate()
$month = $data.getMonth() + 1;
$year = $data.getFullYear()
this.setdata($month, $year, $curDay)
}
// 整理传入的数组
this.formatter_arr=function (fn) {
let arr=fn()
for (var i = 0; i < arr.length; i++) {
var msg = getDay_msg(arr[i].add_time)
arr[i].add_time = msg
}
$model_arr=arr
}
// 补零
function addZero(num) {
return num >= 10 ? num : '0' + num
}
function addHead() {
var headDiv = document.createElement('div');
addClass(headDiv, 'head')
let head_arr = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
for (var i = 0; i < head_arr.length; i++) {
var newspan = document.createElement('span');
newspan.innerText = head_arr[i];
headDiv.appendChild(newspan)
}
$content.appendChild(headDiv)
}
// 设置日历内容
function addBody() {
$body = document.createElement('div');
addClass($body, 'c_body')
// 获取当月的天数
var curmonth_length = getLastDay()
// 设置每一行需要的数据
// 设置一个空数组存放一行需要的数据
var line_arr = [];
for (var i = 1; i <= curmonth_length; i++) {
let push_obj = {
add_time: set_one_day(i)
}
if ($model_arr[i-1]) {
if($model_arr[i-1].add_time.month==$month&&$model_arr[i-1].add_time.year==$year){
push_obj = $model_arr[i-1]
}
}
line_arr.push(push_obj);
if (push_obj.add_time.day == 6 || i == curmonth_length) {
// 当该天为周六,完成一行的数据
let temp = line_arr.concat()
creatLine(temp)
line_arr = []
}
}
$content.appendChild($body)
}
// 获取当前月最后一天
function getLastDay() {
var currentMonth = $data.getMonth();
var nxtMonth = ++currentMonth
// 获取下个月第一天对应的时间
var nxtfirstday = new Date($data.getFullYear(), nxtMonth, 1);
var curLastday = nxtfirstday - 24 * 60 * 60 * 1000;
var lastday = new Date(curLastday);
var lastDate = lastday.getDate();
return lastDate
}
// 设置当月的某一天
function set_one_day(oday) {
var dat = new Date($data.setDate(oday))
return getDay_msg(dat)
}
// 获取当前月每一天对应的数据信息
function getDay_msg(dy) {
var firDay = new Date(dy);
var date = firDay.getDate();
var month = firDay.getMonth()+1
var day = firDay.getDay();
return {
date, day,month
}
}
// 填入医生上下班信息
function show_msg(msg, pnode) {
if (msg) {
for (var k = 0; k < msg.length; k++) {
var pObj = document.createElement('p');
var lump = document.createElement('i')
// lamp表示上下班情况的表示
addClass(lump, 'lump')
if (msg[k].attendance_status_id == 'normal') {
addClass(lump, 'normal')
} else {
addClass(lump, 'late')
}
var text = document.createTextNode(msg[k].attendance_type_name)
pObj.appendChild(lump)
pObj.appendChild(text)
pnode.appendChild(pObj)
}
}
}
function creatLine(arr_receive) {
var newDiv = document.createElement("div");
let tag = arr_receive[0].add_time.day;
// 主要针对第一行不满7个日期
for (let k = tag; k > 0; k--) {
var nullspan = document.createElement('sapn');
newDiv.appendChild(nullspan)
}
for (var i = 0; i < arr_receive.length; i++) {
var dayspan = document.createElement('sapn');
let str = `<i>${arr_receive[i].add_time.date}</i>`
dayspan.innerHTML = str;
if(arr_receive[i].attendance_msg){
show_msg(arr_receive[i].attendance_msg, dayspan)
}
if (arr_receive[i].add_time.date == $curDay) {
addClass(dayspan, 'today')
}
addClass(newDiv, 'line')
newDiv.appendChild(dayspan)
}
// 检测每一行是否有七个,主要针对最后一行
let spanLength = newDiv.children.length;
for (let j = spanLength; j < 7; j++) {
var nullspan = document.createElement('sapn');
newDiv.appendChild(nullspan)
}
// 给一行的日期添加样式
for (var k = 0; k < newDiv.children.length; k++) {
if (k == 0) {
addClass(newDiv.children[k], 'noleft')
}
addClass(newDiv.children[k], 'day')
}
$body.appendChild(newDiv)
}
// 填写日期
function fill_in_date() {
var content_div = $wrap.getElementsByClassName('cur_month')[0];
content_div.innerText = $year + '年' + addZero($month) + '月';
}
this.click=function(){
var pre_btn = $wrap.getElementsByClassName('pre_month')[0];
pre_btn.onclick = function () {
var time = cpmputed('pre');
that.init(time.year, time.month)
}
var nxt_btn = $wrap.getElementsByClassName('nxt_month')[0];
nxt_btn.onclick = function () {
var time = cpmputed('nxt');
that.init(time.year, time.month)
}
}
function cpmputed(tag) {
var month = $month-1, year = $year;
if (tag == 'nxt') {
month = month + 1;
if (month > 11) {
month = 0;
year = year + 1
}
} else if (tag == 'pre') {
month = month - 1;
if (month < 0) {
month = 11;
year = year - 1
}
}
return { year, month }
}
// 给元素添加类名
function addClass(element, classname) {
element.classList.add(classname)
}
this.setdata = function (a, b, c) {
that.data = {
month: a,//当前月份
year: b,//当前年份
curDay: c//当前月中的当前天
}
}
}
let arr = {
"stateMsg": "success",
"stateCode": "200",
"data": [
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-01"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-02"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-03"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-04"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-05"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-06"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-07"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-08"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-09"
},
{
"doctor_id": "1",
"attendance_msg": [
{
"doctor_id": "1",
"attendance_status_name": "正常",
"edit_reason": "测试",
"edit_time": "2019-12-10 15:17:16",
"attendance_type_name": "上班",
"edit_user": "1",
"attendance_address": "北京",
"attendance_status_id": "normal",
"uuid": "1",
"add_time": "2019-12-10 15:17:06",
"attendance_type_id": "attendance_start"
},
{
"doctor_id": "1",
"attendance_status_name": "正常",
"edit_reason": "测试",
"edit_time": "2019-12-10 15:17:16",
"attendance_type_name": "下班",
"edit_user": "1",
"attendance_address": "北京",
"attendance_status_id": "normal",
"uuid": "2",
"add_time": "2019-12-10 15:17:06",
"attendance_type_id": "attendance_off"
}
],
"add_time": "2019-12-10"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-11"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-12"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-13"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-14"
},
{
"doctor_id": "1",
"attendance_msg": [
{
"doctor_id": "1",
"attendance_status_name": "正常",
"edit_reason": "测试",
"edit_time": "2019-12-10 15:17:16",
"attendance_type_name": "下班",
"edit_user": "1",
"attendance_address": "北京",
"attendance_status_id": "normal",
"uuid": "3",
"add_time": "2019-12-15 15:17:06",
"attendance_type_id": "attendance_off"
}
],
"add_time": "2019-12-15"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-16"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-17"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-18"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-19"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-20"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-21"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-22"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-23"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-24"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-25"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-26"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-27"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-28"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-29"
},
{
"doctor_id": "1",
"attendance_msg": [],
"add_time": "2019-12-30"
}
]
}
var ca = new Calend('warp','card')
ca.init(arr,fn);
ca.click()
- css
*{
padding:0;
margin:0;
}
.wrap_card{
margin: 0 auto;
width: 1120px;
height: 666px;
background-color: #ffffff;
box-shadow: 0px 2px 6px 0px
rgba(0, 0, 0, 0.08);
overflow: hidden;
}
.card_title{
height: 62px;
border-bottom: 1px solid #e1e3eb;
line-height: 42px;
font-family: PingFang-SC;
font-size: 16px;
color: #3d404d;
padding: 5px;
}
.title_pic{
display: inline-block;
width: 15px;
height: 15px;
background: url('../css/claend.png') no-repeat -10px -10px;
vertical-align: middle;
margin-right: 5px;
}
.handler_line{
height: 55px;
line-height: 55px;
display: flex;
justify-content: space-between;
}
.handler_month{
font-family: PingFang-SC;
font-size: 14px;
font-weight: normal;
font-stretch: normal;
letter-spacing: 0px;
color: #3d404d;
display: inline-block;
text-align: center;
line-height: 53px;
}
.b_line{
display: block;
width: 40px;
height: 2px;
background-color: #5e72f9;
margin-bottom: 0;
}
.date_show{
display: flex;
align-items: center;
}
.pre_month,
.nxt_month{
line-height: 55px;
}
.pre_month i,
.nxt_month i{
width: 15px;
height: 8px;
display: inline-block;
background: url(../css/claend.png) no-repeat;
}
.pre_month i{
background-position: -13px -32px;
}
.pre_month i:hover{
background-position: -31px -32px;
}
.nxt_month i{
background-position: -13px -49px;
}
.nxt_month i:hover{
background-position: -31px -49px;
}
.cur_month{
margin: 0 20px;
}
.head{
display: flex;
justify-content:space-between;
text-align: center;
border-top: 1px solid #e1e3eb;
}
.head{
height: 50px;
}
.head span{
flex: 1;
line-height: 50px;
}
.c_body{
padding: 5px;
}
.line{
display: flex;
height: 100px;
border-top: 1px solid #e1e3eb;
}
.day{
width: 160px;
padding: 5px;
border-left: 1px solid #e1e3eb;
}
.noleft{
border: 0;
}
.today{
background-color: rgba(59, 130, 253,.3);
}
.lump{
width: 14px;
height: 14px;
border-radius: 1px;
display: inline-block;
vertical-align: middle;
margin-right: 5px;
}
.normal{
background-color: #3b82fd;
}
.late{
background-color: #f79e02;
}
.in_early{
background-color: #ff186a;
}
.warning{
background-color: #ff186a;
}
.day p{
margin-top: 10px;
font-family: PingFang-SC-Regular;
font-size: 14px;
color: #666a80;
}
.pre_month,
.nxt_month,
.day{
cursor: pointer;
}