新的产品需求需要,要写一个这样的日历插件。效果图如下:选择日期后,显示当前可以选择的时间,时间的列表是通过ajax从后台获取的一组数据。
而且这个日期存在的情况,还是动态渲染的一个列表里面,再动态渲染的一个日历。
例如:此时的步骤图渲染是根据后台给的一个list来渲染的,所以,里面的元素但凡要点击,要交互,就要注意事件冒泡。
bootstrap的日历插件,运用起来也没法满足需求,所以被迫自己写了一个日历
代码如下:
var date = new Date()

var nowYear = date.getFullYear(); //获取当前年份

var nowMonth = date.getMonth() + 1; //获取当前月份

var nowDay = date.getDate(); //获取当前天

var splitString = "-"; //年月日之间的分隔符

var weekDays = new Array("日", "一", "二", "三", "四", "五", "六"); //星期数组

var months = new Array("一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"); //月份数组

var lastDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); //每个月的最后一天是几号


//变量保存,存储当前选择的年月

var checkYear = nowYear;

var checkMonth = nowMonth;


// //将选择的日期添加到输入框

function setInput(selectDay) {

$('#txt_calendar').value = checkYear + splitString + checkMonth + splitString + selectDay;

hidDate();

}

// //显示控件

function showDate() {



createDate(nowYear, nowMonth);//创建日历

console.log(nowYear, nowMonth, '创建时间日历')

//计算显示控件位置

///获取当前输入框的位置,在实际操作中需要修改此处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'

})

}

// /*

// * 以下拼接日历框

// * 并定位日历框

// * */

// //创建日历样式

function createDate(thisYear, thisMonth) {

console.log(thisYear, thisMonth, '创建日历------------------')

var createDoc = '
';

//当前年月日,点击此处日历自动跳到当前日期

createDoc += '

当前日期 ' + nowYear + "年" + nowMonth + "月" + nowDay + "号";

//关闭日历显示

createDoc += '×

';;

createDoc += '
';

// 上月

createDoc += '<';

//创建年份下拉框[1900-2099]年onchange="changeYearAndMonth()">

createDoc += '年";

//创建月份下拉框onchange="changeYearAndMonth()">

createDoc += '月";

//下一月 onClick="nextMonthClick()"

createDoc += '>
';

//创建星期

createDoc += '
';

for (var i = 0; i < weekDays.length; i++) {

if (weekDays[i] == "日" || weekDays[i] == "六") {

createDoc += `${weekDays[i]}`

} else {

createDoc += `${weekDays[i]}`

}

}

createDoc += '
';

//创建每月天数

createDoc += '
'; //日期样式DIV

var thisWeek = getThisWeekDay(thisYear, thisMonth, 1); //算出当前年月1号是星期几

/*$(this).css({ 'cursor': 'no-drop' })

* 如果当前不是星期天,创建空白日期占位

* 若是星期天,则循环输出当月天数

* 待修改优化,后期改为变色的前一个月日期

*/

if (thisWeek != 0) {

for (var i = 0; i < thisWeek; i++) {

createDoc += '';

}

}

//循环输出当月天

//getThisMonthDay()获取当月天数

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 += '' + i + '';

//
} else {

//
createDoc += '' + i + '';

//
}

// } else {

// 不可选择的变成灰色, 目前是周末变成灰色

// if (getThisWeekDay(thisYear, thisMonth, i) == 6 || getThisWeekDay(thisYear, thisMonth, i) == 0) {

//
// onClick="setInput(' + i + ')"

//
createDoc += '' + i + '';

// } else {

// console.log(nowDay, 'nowDay-------------')

if (i == nowDay) {

createDoc += `
${i}
`;

} else {

createDoc += `
${i}
`;

}



let weeknum = getThisWeekDay(thisYear, thisMonth, i)

let weektext = '周' + weekDays[weeknum]

for (let _i = 0; _i < interviewtimelist.length; _i++) {

if (weeknum == interviewtimelist[_i].week) {

createDoc += `

${weektext} ${interviewtimelist[_i].amorpm} ${interviewtimelist[_i].time}

`

}

}

createDoc += '
'




// }

// }

//星期六换行

if (getThisWeekDay(thisYear, thisMonth, i) == 6) {

createDoc += "";

}

}

createDoc += '
';

$('#testID').html(createDoc)

//将创建好的控件字符串添加到div中

//默认选择当前年份

console.log(thisMonth, '当前月份为-------------')

$('#selectYear').val(thisYear)

//默认选择当前月

$('#selectMonth').val(thisMonth)

if (thisMonth == 1) {

$('#selectMonth').val('1')

}

console.log(thisMonth, '当前月份为-------------', $('#selectMonth').val())

}//日历创建结束

// //跳转到当前日

function getThisDay() {

checkYear = nowYear;

checkMonth = nowMonth;

createDate(checkYear, checkMonth);

}


//上一个月

$(document).on('click', '#lastMonth', function (event) {

event.stopPropagation()

lastMonthClick()

})

function lastMonthClick() {

//若当前是1月份,年份减一,月份变为12

if (checkMonth == 1) {

checkYear = checkYear - 1;

checkMonth = 12;

} else {

checkMonth = checkMonth - 1;

}

//创建当前月份日期

createDate(checkYear, checkMonth);

}


//下一月

$(document).on('click', '#nextMonth', function (event) {

event.stopPropagation()

nextMonthClick()

})

function nextMonthClick() {

//若当前是12月份,年份加1,月份变为1

if (checkMonth == 12) {

checkYear = parseInt(checkYear + 1);

checkMonth = 1;

} else {

checkMonth = parseInt(checkMonth + 1);

}

//创建当前月份日期

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;

}


//获取某月份的总天数

function getThisMonthDay(year, month) {

var thisDayCount = lastDays[month - 1]; //获取当前月份的天数

if ((month == 2) && isLeapYear(year)) {

//若当前月份为2月,并且是闰年,天数加1

thisDayCount++;

}

return thisDayCount;

}


//计算某天是星期几

function getThisWeekDay(year, month, date) {

//将年月日创建Date对象,返回当前星期几

var thisDate = new Date(year, month - 1, date);

return thisDate.getDay();

}

/**

*

* @param {*} curdate 鼠标滑过的日期

* @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) { // 不可点击的状态

$(this).css({ 'cursor': 'no-drop' })

$(this).siblings().children('.timeList').hide()

return

} else { // 可点击的状态

$(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) { // 不可点击的状态

$(this).siblings().children('.timeList').hide()

return

} else { // 可点击的状态

$(this).children('.timeList').show()

$(this).siblings().children('.timeList').hide()

}

})

/**

* 点击选择当前时间var curClickStatus = ''

var curInterViewDate = ''

var curInterViewTime = ''

var curAmPm = ''

* 更新页面的显示,以及保存参数后续点击确定的时候,传给后台

*/

$(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()

})

/**

* 点击面试时间的元素。渲染到页面“请选择面试时间” “”

* 隐藏日历并恢复日历最初的值。

*

*/

$(document).on('click', '.anyDay', function (event) {

event.stopPropagation()

if ($(this).children().children().length <= 0) { // 不可点击的状态

$(this).css({ 'cursor': 'no-drop' })

return

} else { // 可点击的状态

$(this).children('.timeList').show()

$(this).siblings().children('.timeList').hide()

}

console.log(this, '点击当前元素----', $(this).children().children().length)

})

// //关闭日期选择框

function hidDate() {

$('#dateOuter').style.display = "none";

}
var date = new Date()

var nowYear = date.getFullYear(); //获取当前年份

var nowMonth = date.getMonth() + 1; //获取当前月份

var nowDay = date.getDate(); //获取当前天

var splitString = "-"; //年月日之间的分隔符

var weekDays = new Array("日", "一", "二", "三", "四", "五", "六"); //星期数组

var months = new Array("一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"); //月份数组

var lastDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); //每个月的最后一天是几号


//变量保存,存储当前选择的年月

var checkYear = nowYear;

var checkMonth = nowMonth;


// //将选择的日期添加到输入框

function setInput(selectDay) {

$('#txt_calendar').value = checkYear + splitString + checkMonth + splitString + selectDay;

hidDate();

}

// //显示控件

function showDate() {



createDate(nowYear, nowMonth);//创建日历

console.log(nowYear, nowMonth, '创建时间日历')

//计算显示控件位置

///获取当前输入框的位置,在实际操作中需要修改此处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'

})

}

// /*

// * 以下拼接日历框

// * 并定位日历框

// * */

// //创建日历样式

function createDate(thisYear, thisMonth) {

console.log(thisYear, thisMonth, '创建日历------------------')

var createDoc = '
';

//当前年月日,点击此处日历自动跳到当前日期

createDoc += '

当前日期 ' + nowYear + "年" + nowMonth + "月" + nowDay + "号";

//关闭日历显示

createDoc += '×

';;

createDoc += '
';

// 上月

createDoc += '<';

//创建年份下拉框[1900-2099]年onchange="changeYearAndMonth()">

createDoc += '年";

//创建月份下拉框onchange="changeYearAndMonth()">

createDoc += '月";

//下一月 onClick="nextMonthClick()"

createDoc += '>
';

//创建星期

createDoc += '
';

for (var i = 0; i < weekDays.length; i++) {

if (weekDays[i] == "日" || weekDays[i] == "六") {

createDoc += `${weekDays[i]}`

} else {

createDoc += `${weekDays[i]}`

}

}

createDoc += '
';

//创建每月天数

createDoc += '
'; //日期样式DIV

var thisWeek = getThisWeekDay(thisYear, thisMonth, 1); //算出当前年月1号是星期几

/*$(this).css({ 'cursor': 'no-drop' })

* 如果当前不是星期天,创建空白日期占位

* 若是星期天,则循环输出当月天数

* 待修改优化,后期改为变色的前一个月日期

*/

if (thisWeek != 0) {

for (var i = 0; i < thisWeek; i++) {

createDoc += '';

}

}

//循环输出当月天

//getThisMonthDay()获取当月天数

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 += '' + i + '';

//
} else {

//
createDoc += '' + i + '';

//
}

// } else {

// 不可选择的变成灰色, 目前是周末变成灰色

// if (getThisWeekDay(thisYear, thisMonth, i) == 6 || getThisWeekDay(thisYear, thisMonth, i) == 0) {

//
// onClick="setInput(' + i + ')"

//
createDoc += '' + i + '';

// } else {

// console.log(nowDay, 'nowDay-------------')

if (i == nowDay) {

createDoc += `
${i}
`;

} else {

createDoc += `
${i}
`;

}



let weeknum = getThisWeekDay(thisYear, thisMonth, i)

let weektext = '周' + weekDays[weeknum]

for (let _i = 0; _i < interviewtimelist.length; _i++) {

if (weeknum == interviewtimelist[_i].week) {

createDoc += `

${weektext} ${interviewtimelist[_i].amorpm} ${interviewtimelist[_i].time}

`

}

}

createDoc += '
'




// }

// }

//星期六换行

if (getThisWeekDay(thisYear, thisMonth, i) == 6) {

createDoc += "";

}

}

createDoc += '
';

$('#testID').html(createDoc)

//将创建好的控件字符串添加到div中

//默认选择当前年份

console.log(thisMonth, '当前月份为-------------')

$('#selectYear').val(thisYear)

//默认选择当前月

$('#selectMonth').val(thisMonth)

if (thisMonth == 1) {

$('#selectMonth').val('1')

}

console.log(thisMonth, '当前月份为-------------', $('#selectMonth').val())

}//日历创建结束

// //跳转到当前日

function getThisDay() {

checkYear = nowYear;

checkMonth = nowMonth;

createDate(checkYear, checkMonth);

}


//上一个月

$(document).on('click', '#lastMonth', function (event) {

event.stopPropagation()

lastMonthClick()

})

function lastMonthClick() {

//若当前是1月份,年份减一,月份变为12

if (checkMonth == 1) {

checkYear = checkYear - 1;

checkMonth = 12;

} else {

checkMonth = checkMonth - 1;

}

//创建当前月份日期

createDate(checkYear, checkMonth);

}


//下一月

$(document).on('click', '#nextMonth', function (event) {

event.stopPropagation()

nextMonthClick()

})

function nextMonthClick() {

//若当前是12月份,年份加1,月份变为1

if (checkMonth == 12) {

checkYear = parseInt(checkYear + 1);

checkMonth = 1;

} else {

checkMonth = parseInt(checkMonth + 1);

}

//创建当前月份日期

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;

}


//获取某月份的总天数

function getThisMonthDay(year, month) {

var thisDayCount = lastDays[month - 1]; //获取当前月份的天数

if ((month == 2) && isLeapYear(year)) {

//若当前月份为2月,并且是闰年,天数加1

thisDayCount++;

}

return thisDayCount;

}


//计算某天是星期几

function getThisWeekDay(year, month, date) {

//将年月日创建Date对象,返回当前星期几

var thisDate = new Date(year, month - 1, date);

return thisDate.getDay();

}

/**

*

* @param {*} curdate 鼠标滑过的日期

* @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) { // 不可点击的状态

$(this).css({ 'cursor': 'no-drop' })

$(this).siblings().children('.timeList').hide()

return

} else { // 可点击的状态

$(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) { // 不可点击的状态

$(this).siblings().children('.timeList').hide()

return

} else { // 可点击的状态

$(this).children('.timeList').show()

$(this).siblings().children('.timeList').hide()

}

})

/**

* 点击选择当前时间var curClickStatus = ''

var curInterViewDate = ''

var curInterViewTime = ''

var curAmPm = ''

* 更新页面的显示,以及保存参数后续点击确定的时候,传给后台

*/

$(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()

})

/**

* 点击面试时间的元素。渲染到页面“请选择面试时间” “”

* 隐藏日历并恢复日历最初的值。

*

*/

$(document).on('click', '.anyDay', function (event) {

event.stopPropagation()

if ($(this).children().children().length <= 0) { // 不可点击的状态

$(this).css({ 'cursor': 'no-drop' })

return

} else { // 可点击的状态

$(this).children('.timeList').show()

$(this).siblings().children('.timeList').hide()

}

console.log(this, '点击当前元素----', $(this).children().children().length)

})

// //关闭日期选择框

function hidDate() {

$('#dateOuter').style.display = "none";

}目前可以实现需求了,但还有很多的不足,如果有好的建议,欢迎留言哦~
标签:

你有充足的理由选择我们

深圳上海杭州北京前端外包开发:工作10年以上的小伙伴团队,前端开发工作是我们最大的事业。所有您担心的问题,都可以写到合同里。我们会100%努力完成,直到您满意!