jQuery實現(xiàn)可以擴(kuò)展的日歷
新的產(chǎn)品需求需要,要寫一個這樣的日歷插件。
效果圖如下:

選擇日期后,顯示當(dāng)前可以選擇的時間,時間的列表是通過ajax從后臺獲取的一組數(shù)據(jù)。
而且這個日期存在的情況,還是動態(tài)渲染的一個列表里面,再動態(tài)渲染的一個日歷。
例如:

此時的步驟圖渲染是根據(jù)后臺給的一個list來渲染的,所以,里面的元素但凡要點擊,要交互,就要注意事件冒泡。
bootstrap的日歷插件,運用起來也沒法滿足需求,所以被迫自己寫了一個日歷
代碼如下:
var date = new Date()
var nowYear = date.getFullYear(); //獲取當(dāng)前年份
var nowMonth = date.getMonth() + 1; //獲取當(dāng)前月份
var nowDay = date.getDate(); //獲取當(dāng)前天
var splitString = "-"; //年月日之間的分隔符
var weekDays = new Array("日", "一", "二", "三", "四", "五", "六"); //星期數(shù)組
var months = new Array("一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"); //月份數(shù)組
var lastDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); //每個月的最后一天是幾號
//變量保存,存儲當(dāng)前選擇的年月
var checkYear = nowYear;
var checkMonth = nowMonth;
// //將選擇的日期添加到輸入框
function setInput(selectDay) {
$('#txt_calendar').value = checkYear + splitString + checkMonth + splitString + selectDay;
hidDate();
}
// //顯示控件
function showDate() {
createDate(nowYear, nowMonth);//創(chuàng)建日歷
console.log(nowYear, nowMonth, '創(chuàng)建時間日歷')
//計算顯示控件位置
///獲取當(dāng)前輸入框的位置,在實際操作中需要修改此處ID
var x = $('#txt_calendar').offset().left
var y = $('#txt_calendar').offset().top + 22
console.log(x, y, 'x, y', $('#txt_calendar'))
$('#testID').css({
left: '-38px',
top: '37px'
})
}
// /*
// * 以下拼接日歷框
// * 并定位日歷框
// * */
// //創(chuàng)建日歷樣式
function createDate(thisYear, thisMonth) {
console.log(thisYear, thisMonth, '創(chuàng)建日歷------------------')
var createDoc = '<div style="height: 30px;">';
//當(dāng)前年月日,點擊此處日歷自動跳到當(dāng)前日期
createDoc += '<p style="width: 100%;height: 30px;text-align: center;color: #999; display: none;" onclick="getThisDay()">當(dāng)前日期 ' + nowYear + "年" + nowMonth + "月" + nowDay + "號";
//關(guān)閉日歷顯示
createDoc += '<span id="closeDate" onClick="hidDate()" style="float: right;font-size: 25px;margin: -20px 3px 0 0;cursor: pointer;">×</span></p></div>';;
createDoc += '<div style="margin-bottom: 8px;">';
// 上月
createDoc += '<span id="lastMonth" style="margin: 0 20px 0 25px;cursor:pointer;"><</span>';
//創(chuàng)建年份下拉框[1900-2099]年onchange="changeYearAndMonth()">
createDoc += '<select id ="selectYear" class="selectStyle"';
for (var y = 1900; y <= 2099; y++) {
createDoc += "<option value=" + y + ">" + y + "</option>";
}
createDoc += "</select>年";
//創(chuàng)建月份下拉框onchange="changeYearAndMonth()">
createDoc += '<select id ="selectMonth" style="overflow: auto;" class="selectStyle"';
for (var m = 0; m <= 12; m++) {
createDoc += `<option style='z-index: 9999;' value="${m}">${m}</option>`;
}
createDoc += "</select>月";
//下一月 onClick="nextMonthClick()"
createDoc += '<span id="nextMonth"style="float: right;margin-right: 25px;cursor:pointer; padding-left: 10px;">></span></div>';
//創(chuàng)建星期
createDoc += '<div class="everyWeekDay">';
for (var i = 0; i < weekDays.length; i++) {
if (weekDays[i] == "日" || weekDays[i] == "六") {
createDoc += `<span class="weekday" style="background-color: #18bc9c;color:#ccc;">${weekDays[i]}</span>`
} else {
createDoc += `<span style="background-color: #18bc9c;color:#fff;" class="weekday">${weekDays[i]}</span>`
}
}
createDoc += '</div>';
//創(chuàng)建每月天數(shù)
createDoc += '<div class="everyDay"><div class="marginTop">'; //日期樣式DIV
var thisWeek = getThisWeekDay(thisYear, thisMonth, 1); //算出當(dāng)前年月1號是星期幾
/*$(this).css({ 'cursor': 'no-drop' })
* 如果當(dāng)前不是星期天,創(chuàng)建空白日期占位
* 若是星期天,則循環(huán)輸出當(dāng)月天數(shù)
* 待修改優(yōu)化,后期改為變色的前一個月日期
*/
if (thisWeek != 0) {
for (var i = 0; i < thisWeek; i++) {
createDoc += '<span class="days"></span>';
}
}
//循環(huán)輸出當(dāng)月天
//getThisMonthDay()獲取當(dāng)月天數(shù)
for (var i = 1; i < getThisMonthDay(thisYear, thisMonth) + 1; i++) {
// if (thisYear == nowYear && thisMonth == nowMonth && i == nowDay) {
// //今天的顯示
// if (getThisWeekDay(thisYear, thisMonth, i) == 6 || getThisWeekDay(thisYear, thisMonth, i) == 0) {
// //今天是周末
// createDoc += '<span class="days anyDay" data- style="background-color:#4eccc4;color:#FFFFFF;cursor:pointer;">' + i + '</span>';
// } else {
// createDoc += '<span class="days anyDay" style="background-color:#4eccc4;color:#FFFFFF;cursor:pointer;">' + i + '</span>';
// }
// } else {
// 不可選擇的變成灰色, 目前是周末變成灰色
// if (getThisWeekDay(thisYear, thisMonth, i) == 6 || getThisWeekDay(thisYear, thisMonth, i) == 0) {
// // onClick="setInput(' + i + ')"
// createDoc += '<span id="weekends" class="days anyDay"" style="color:#ccc; cursor:pointer;">' + i + '</span>';
// } else {
// console.log(nowDay, 'nowDay-------------')
if (i == nowDay) {
createDoc += `<div class="days anyDay" data-date="${thisYear}-${thisMonth}-${i}" style="cursor:pointer;background-color:#4eccc4;color:#FFFFFF;">${i}<div class="timeList">`;
} else {
createDoc += `<div class="days anyDay" data-date="${thisYear}-${thisMonth}-${i}" style="cursor:pointer;">${i}<div class="timeList">`;
}
let weeknum = getThisWeekDay(thisYear, thisMonth, i)
let weektext = '周' + weekDays[weeknum]
for (let _i = 0; _i < interviewtimelist.length; _i++) {
if (weeknum == interviewtimelist[_i].week) {
createDoc += `<p class='interViewTime' style="width: 100%; border-bottom: 1px solid #ccc;" data-week="${interviewtimelist[_i].week}" data-time="${interviewtimelist[_i].time}" data-amorpm="${interviewtimelist[_i].amorpm}">${weektext} ${interviewtimelist[_i].amorpm} ${interviewtimelist[_i].time}</p>`
}
}
createDoc += '</div></div>'
// }
// }
//星期六換行
if (getThisWeekDay(thisYear, thisMonth, i) == 6) {
createDoc += "</tr>";
}
}
createDoc += '</div></div>';
$('#testID').html(createDoc)
//將創(chuàng)建好的控件字符串添加到div中
//默認(rèn)選擇當(dāng)前年份
console.log(thisMonth, '當(dāng)前月份為-------------')
$('#selectYear').val(thisYear)
//默認(rèn)選擇當(dāng)前月
$('#selectMonth').val(thisMonth)
if (thisMonth == 1) {
$('#selectMonth').val('1')
}
console.log(thisMonth, '當(dāng)前月份為-------------', $('#selectMonth').val())
}//日歷創(chuàng)建結(jié)束
// //跳轉(zhuǎn)到當(dāng)前日
function getThisDay() {
checkYear = nowYear;
checkMonth = nowMonth;
createDate(checkYear, checkMonth);
}
//上一個月
$(document).on('click', '#lastMonth', function (event) {
event.stopPropagation()
lastMonthClick()
})
function lastMonthClick() {
//若當(dāng)前是1月份,年份減一,月份變?yōu)?2
if (checkMonth == 1) {
checkYear = checkYear - 1;
checkMonth = 12;
} else {
checkMonth = checkMonth - 1;
}
//創(chuàng)建當(dāng)前月份日期
createDate(checkYear, checkMonth);
}
//下一月
$(document).on('click', '#nextMonth', function (event) {
event.stopPropagation()
nextMonthClick()
})
function nextMonthClick() {
//若當(dāng)前是12月份,年份加1,月份變?yōu)?
if (checkMonth == 12) {
checkYear = parseInt(checkYear + 1);
checkMonth = 1;
} else {
checkMonth = parseInt(checkMonth + 1);
}
//創(chuàng)建當(dāng)前月份日期
createDate(checkYear, checkMonth);
}
//年月下拉框-年selectMonth
$(document).on('click', '.selectStyle', function (event) {
event.stopPropagation()
})
$(document).on('click', '.selectStyle option', function (event) {
event.stopPropagation()
})
// 點擊年份
$(document).on('change', '#selectYear', function (event) {
event.stopPropagation()
changeYearAndMonth()
})
//年月下拉框-月
$(document).on('change', '#selectMonth', function (event) {
event.stopPropagation()
changeYearAndMonth()
})
function changeYearAndMonth() {
checkYear = $('#selectYear').val()
checkMonth = $('#selectMonth').val();
createDate(checkYear, checkMonth);
}
//判斷是否為閏年
function isLeapYear(year) {
var isLeap = false;
if (0 == year % 4 && ((year % 100 != 0) || (year % 400 == 0))) {
//閏年可以被4整除且不能被100整除,或者能整除400
isLeap = true;
}
return isLeap;
}
//獲取某月份的總天數(shù)
function getThisMonthDay(year, month) {
var thisDayCount = lastDays[month - 1]; //獲取當(dāng)前月份的天數(shù)
if ((month == 2) && isLeapYear(year)) {
//若當(dāng)前月份為2月,并且是閏年,天數(shù)加1
thisDayCount++;
}
return thisDayCount;
}
//計算某天是星期幾
function getThisWeekDay(year, month, date) {
//將年月日創(chuàng)建Date對象,返回當(dāng)前星期幾
var thisDate = new Date(year, month - 1, date);
return thisDate.getDay();
}
/**
*
* @param {*} curdate 鼠標(biāo)滑過的日期
* @param {*} today 今天的日期
*/
function compareDate(curdate) {
let today = Date.parse(nowYear + '-' + nowMonth + '-' + nowDay)
let cur = Date.parse(curdate)
if (cur <= today) {
return false
} else {
return true
}
// var cur = curdate.split('-')
// var c = Date.parse(curdate)
}
$(document).on('mouseover', '.anyDay', function (event) {
event.stopPropagation()
console.log($(this).context.dataset.date)
let canclick = compareDate($(this).context.dataset.date) ? true : false
if ($(this).children().children().length <= 0 || !canclick) { // 不可點擊的狀態(tài)
$(this).css({ 'cursor': 'no-drop' })
$(this).siblings().children('.timeList').hide()
return
} else { // 可點擊的狀態(tài)
$(this).children('.timeList').show()
$(this).siblings().children('.timeList').hide()
}
})
$(document).on('click', '.anyDay', function (event) {
event.stopPropagation()
let canclick = compareDate($(this).context.dataset.date) ? true : false
curInterViewDate = $(this).context.dataset.date
if ($(this).children().children().length <= 0 || !canclick) { // 不可點擊的狀態(tài)
$(this).siblings().children('.timeList').hide()
return
} else { // 可點擊的狀態(tài)
$(this).children('.timeList').show()
$(this).siblings().children('.timeList').hide()
}
})
/**
* 點擊選擇當(dāng)前時間var curClickStatus = ''
var curInterViewDate = ''
var curInterViewTime = ''
var curAmPm = ''
* 更新頁面的顯示,以及保存參數(shù)后續(xù)點擊確定的時候,傳給后臺
*/
$(document).on('click', '.interViewTime', function (event) {
event.stopPropagation()
// curInterViewDate = $(this).context.dataset.
let week = '周' + weekDays[$(this).context.dataset.week]
curInterViewTime = $(this).context.dataset.time
curAmPm = $(this).context.dataset.amorpm
console.log($(this))
let text_input = week + ' ' + curInterViewDate + ' ' + curAmPm + ' ' + curInterViewTime
$('#txt_calendar').val(text_input)
$('#testID').hide()
})
/**
* 點擊面試時間的元素。渲染到頁面“請選擇面試時間” “”
* 隱藏日歷并恢復(fù)日歷最初的值。
*
*/
$(document).on('click', '.anyDay', function (event) {
event.stopPropagation()
if ($(this).children().children().length <= 0) { // 不可點擊的狀態(tài)
$(this).css({ 'cursor': 'no-drop' })
return
} else { // 可點擊的狀態(tài)
$(this).children('.timeList').show()
$(this).siblings().children('.timeList').hide()
}
console.log(this, '點擊當(dāng)前元素----', $(this).children().children().length)
})
// //關(guān)閉日期選擇框
function hidDate() {
$('#dateOuter').style.display = "none";
}
目前可以實現(xiàn)需求了,但還有很多的不足,如果有好的建議,歡迎留言哦~
相關(guān)文章
實現(xiàn)點擊下箭頭變上箭頭來回切換的兩種方法【推薦】
本文主要介紹了實現(xiàn)點擊下箭頭變上箭頭來回切換的兩種方法,具有很好的參考價值,需要的朋友一起來看下吧2016-12-12
實例講解jQuery EasyUI tree中state屬性慎用
本文通過實例代碼給大家介紹jQuery EasyUI tree中state屬性慎用,切忌把state設(shè)置為closed,否則該節(jié)點會加載整個tree,形成死循環(huán)2016-04-04
jQuery旋轉(zhuǎn)插件—rotate支持(ie/Firefox/SafariOpera/Chrome)
網(wǎng)上發(fā)現(xiàn)一個很有意思的jQuery旋轉(zhuǎn)插件,支持Internet Explorer 6.0+ 、Firefox 2.0 、Safari 3 、Opera 9 、Google Chrome,高級瀏覽器下使用Transform,低版本ie使用VML實現(xiàn),感興趣的朋友可以了解下2013-01-01

