忙里偷閑乐设,終于有點時間寫博客了众雷。今天我要說的這款插件灸拍,是我自己在項目中開發(fā)的。前段時間花了好多心思Google砾省,找了很多的插件鸡岗,但是沒有一款符合項目要求。想想自己雖然不是什么技術(shù)大牛编兄,但是寫個拙劣的插件應(yīng)該還是可行的轩性。于是花了一天時間把流程及基礎(chǔ)功能做好了,又繼續(xù)花了一天時間完善了下翻诉,現(xiàn)在看來炮姨,也沒有白費心思捌刮。至少這個東西沒有走向滅亡,而是繼續(xù)在項目中實現(xiàn)它的價值舒岸。好了绅作,廢話不多說,上菜蛾派!
日歷開源俄认,已經(jīng)放在github上面了。git@github.com:BGOnline-CN/BGOCalender.git
博客中有什么不對的地方洪乍,希望大家能幫我指出來眯杏,冰果在這里先謝過了!
1.買房子壳澳,一定得隔音岂贩!
;(function($) {
// 這里是我們的插件代碼
})(jQuery);
2.打掃衛(wèi)生
;(function($) {
$.fn.extend({ // 這里是我們的插件代碼
'BGOCalender': function(options) { // 開始寫插件,BGOCalender就是我們的插件名
}
});
})(jQuery);
3.通水電巷波,哥們以前通下水道的萎津,這個難不倒我。嘿嘿嘿~
;(function($) {
$.fn.extend({ // 這里是我們的插件代碼
'BGOCalender': function(options) { // 開始寫插件抹镊,BGOCalender就是我們的插件名
// 既然是日歷插件锉屈,那少不了的東西就是 Date() 方法啦
var date = new Date(); // 實例化 日期函數(shù)
// 1.好了,房子打掃干凈了垮耳,咋們把水電通通吧颈渊。(默認(rèn)參數(shù)配置)
var defaultOpts = {
today: date.getDate(), // 當(dāng)天
month: date.getMonth(), // 當(dāng)月
year: date.getFullYear(), // 當(dāng)年
data: [], // 接收服務(wù)器數(shù)據(jù)
language: cn, // 語言
callback: function() {} //回調(diào)函數(shù)
}
// 接收用戶自定義參數(shù) options 如果有則覆蓋默認(rèn)參數(shù),否則使用默認(rèn)參數(shù)
var opts = $.extend(defaultOpts, options || {});
var monthDays = [31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // 一年中终佛,每月的天數(shù)俊嗽,這里你可能會發(fā)現(xiàn)2月有點奇怪,不是還有閏月嗎查蓉?好的乌询,不急,咋們后面會處理豌研。
var cn = {
weekLang: ['\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u65e5'], // 周一到周日妹田,中文語言包
//monthLang: ['\u4e00\u6708', '\u4e8c\u6708', '\u4e09\u6708', '\u56db\u6708', '\u4e94\u6708', '\u516d\u6708', '\u4e03\u6708', '\u516b\u6708', '\u4e5d\u6708', '\u5341\u6708', '\u5341\u4e00\u6708', '\u5341\u4e8c\u6708'] // 月份的語言包,我沒做鹃共,因為項目中并沒有用到
}
// 好了鬼佣,接下來,處理我們的平年閏年了
var isLeapYear = function(y, m) { // 前面的開發(fā)規(guī)范我有說過霜浴,只包含一條語句的代碼塊晶衷,我們可以再一行內(nèi)顯示
if(m < 0) { m = 11; } // 這里的作用是,JS返回給我們的月份是從0開始的,也就是說晌纫,我們想要得到1月税迷,必須得告訴他我們要的是0月,所以我們要做個判斷锹漱,以便我們切換年份時使用
if(m > 11) { m = 0; }
if(m == 1) { // 判斷是否為閏年箭养,并返回該月天數(shù)
return ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) ? 29 : 28;
}else { return monthDays[m]; }
}
// 返回上一個月天數(shù)
var preMonthDays = function(y, m) {
return isLeapYear(y, m-1);
}
// 返回該月第一天是星期幾
var firstDayWeek = function(y, m) {
return new Date(y, m, 1).getDay() == 0 ? 7 : new Date(y, m, 1).getDay();
}
// 日歷表頭
for(var i = 0; i < cn.weekLang.length; i++) {
$('> .calender > table > thead > tr > th', this).eq(i).html(opts.language.weekLang[i]);
}
}
});
})(jQuery);
到這里,結(jié)合我們的html哥牍,一個簡單的日歷就出來了毕泌。
這個日歷的html我是直接分開來寫的,沒有用js生成嗅辣。為了擴展性和方便項目撼泛,你們有需要可以自行修改。
4.實現(xiàn)上一個月與下一個月功能
// 載入今天和當(dāng)月澡谭,在項目中用不上愿题,所以我注釋掉了
// // 載入今天
// $('.cur').click(function() {
// opts.month = date.getMonth();
// opts.year = date.getFullYear();
// opts.today = date.getDate();
// td.removeClass('selectDate');
// initCalender(opts.year, opts.month);
// });
// // 載入當(dāng)月
// $('.cur').click(function() {
// opts.month = date.getMonth();
// opts.year = date.getFullYear();
// initCalender(opts.year, opts.month);
// });
// 載入上一個月
$('.preClass').click(function() {
opts.month--;
if(opts.month < 0) {
opts.month = 11;
opts.year--;
}
initCalender(opts.year, opts.month);
});
// 載入下一個月
$('.nextClass').click(function() {
opts.month++;
if(opts.month > 11) {
opts.month = 0;
opts.year++;
}
initCalender(opts.year, opts.month);
});
5.載入日歷
cData = [];
sData = [];
var showSelectInfo = function(totalData) {
var removeRepeat = function(index,array) { // 根據(jù)指定下標(biāo)刪除數(shù)組 供過濾時調(diào)用
if(index >= 0 && index < array.length) {
for(var i = index; i < array.length; i++) {
array[i] = array[i+1];
}
array.length = array.length - 1;
}
return array;
}
var filterArray = function(arr) { // 過濾數(shù)組中重復(fù)數(shù)據(jù)并返回新數(shù)組
for(var i=0; i< arr.length; i++) {
for(var j = i + 1; j < arr.length; j++) {
if(arr[i] == arr[j]) {
arr = removeRepeat(j,arr);
i = -1;
break;
}
}
}
return arr;
}
var bubbling = function(arr) { // 排序
var flag = false;
var temp;
for(var i = 0; i < arr.length - 1; i++) {
for(var j = 0; j < arr.length-1-i; j++) {
if(arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = true;
}
}
if(flag) {
flag = false;
}else {
break;
}
}
}
totalData = filterArray(totalData);
bubbling(totalData);
// 右側(cè)顯示數(shù)值
switch(opts.pattern) {
case 1:
$('.startClass > span.dateTitle').html('開班日期');
$('.endClass > span.dateTitle').html('結(jié)班日期');
break;
case 2:
$('.startClass > span.dateTitle').html('上課日期');
$('.endClass > span.dateTitle').html('結(jié)課日期');
break;
}
if(totalData.length < 1) {
$('.startClass > span.dateCon').html(''); // 開課日期
$('.endClass > span.dateCon').html(''); // 結(jié)課日期
}else {
$('.startClass > span.dateCon').html(totalData[0]); // 開課日期
$('.endClass > span.dateCon').html(totalData[totalData.length-1]); // 結(jié)課日期
}
$('.totalClass > p > span').html(totalData.length); // 總上課天數(shù)
// 剩余上課天數(shù)
var count = 0;
var fullToday;
if(date.getMonth() < 10 && date.getDate() < 10) {
fullToday = date.getFullYear() + '-' + '0' + (date.getMonth() + 1) + '-' + '0' + date.getDate();
}else if(date.getMonth() < 10 && date.getDate() > 10) {
fullToday = date.getFullYear() + '-' + '0' + (date.getMonth() + 1) + '-' + date.getDate();
}else if(date.getMonth() > 10 && date.getDate() < 10) {
fullToday = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + '0' + date.getDate();
}else if(date.getMonth() > 10 && date.getDate() > 10) {
fullToday = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
}
for(var i = 0; i < totalData.length; i++) {
if(totalData[i] >= fullToday) {
count++;
}
}
$('.onlyClass > p > span').html(count);
}
var addTotalData = function(e, totalData) { // 載入totalData
if(e.text() < 10) {
totalData.push($('.year').text()+'-'+$('.month').text()+'-'+'0'+e.text());
}else {
totalData.push($('.year').text()+'-'+$('.month').text()+'-'+e.text());
}
}
var removeTotalData = function(e, totalData) { // 刪除totalData
if(e.text() < 10) {
totalData.splice($.inArray($('.year').text()+'-'+$('.month').text()+'-'+'0'+e.text(), totalData),1);
}else {
totalData.splice($.inArray($('.year').text()+'-'+$('.month').text()+'-'+e.text(), totalData),1);
}
}
var generateCalendar = function(y, m) {
// 當(dāng)前所在日期
$('.year').html(y);
if(m+1 < 10) {
$('.month').html('0'+parseInt(m+1));
}else {
$('.month').html(parseInt(m+1));
}
var data = [];
// 用上月號數(shù)補齊當(dāng)月1號前空余號數(shù)
for(var i = firstDayWeek(y, m) - 2; i >= 0; i--) {
data.push('<span class="notMonthly">' + (preMonthDays(y, m)-i) + '</span>');
}
// if($('.month').text() < 10) { // 拼裝參數(shù)
// var holiday = $('.year').text()+'0'+$('.month').text();
// }else {
// var holiday = $('.year').text()+$('.month').text();
// }
// $.ajax({ // 獲取節(jié)假日數(shù)據(jù)
// type: "GET",
// url: "http://apis.baidu.com/xiaogg/holiday/holiday",
// data: {d: holiday, apikey: '22ccbd220dba0561bbe2177d84d501cf'},
// headers : {'apikey':''},
// dataType: "json",
// success: function(response) {
// var res = response[holiday];
// for(var k = 0; k <= res.length; k++) {
// for(var i = 1; i <= 31; i++) {
// if(i == res[k].slice(2)) {
// // if(td.eq(i).text() == i) {
// // //td.eq(i).addClass('holiday')
// // alert(td.eq(i).text())
// // }
// }
// }
// }
// }
// });
// 獲得當(dāng)月號數(shù)
for(var i = 1; i <= isLeapYear(y, m); i++) {
data.push(i);
}
// 用下月號數(shù)補齊當(dāng)月最后空余號數(shù)
var lackNum = td.length - data.length;
for(var i = 1; i <= lackNum; i++) {
data.push('<span class="notMonthly">' + i + '</span>');
}
// 載入日歷
for(var i = 0; i < data.length; i++) {
td.eq(i).html(data[i]);
if(data[i] < 10) {
td.eq(i).attr({name:$('.year').text() + '-' + $('.month').text() + '-' + '0' + data[i]});
}else {
td.eq(i).attr({name:$('.year').text() + '-' + $('.month').text() + '-' + data[i]});
}
for(var k = 0; k < cData.length; k++) {
if(td.eq(i).attr('name') == cData[k]) {
td.eq(i).addClass('selectDate');
}
}
for(var j = 0; j < sData.length; j++) {
if(td.eq(i).attr('name') == sData[j]) {
td.eq(i).addClass('selectStuDate');
}
}
}
// 周末特別標(biāo)識
for(var i = firstDayWeek(y, m) - 1; i <= isLeapYear(y, m) + firstDayWeek(y, m) - 2; i++) {
if(new Date(y, m, parseInt(td.eq(i).text())).getDay() == 0 || new Date(y, m, parseInt(td.eq(i).text())).getDay() == 6) {
td.eq(i).addClass('holiday');
}
}
}
6.日歷初始化
switch(opts.pattern) {
case 1: // 開課日歷
// 初始化日歷
var initCalender = function(y, m) {
showSelectInfo(cData);
// 復(fù)位checkbox
$('.selectWeekend').removeAttr('checked');
$('.selectAll').removeAttr('checked');
td.removeClass('selectDate');
generateCalendar(y, m);
}
cData = [];
// 用戶參數(shù) data 與 歷史cData 并集
var mergeArray = function(arr1, arr2) {
for (var i = 0, j = 0, ci, r = {}, c = []; ci = arr1[i++] || arr2[j++]; ) {
if (r[ci]) continue;
r[ci] = 1;
c.push(ci);
}
return c;
}
cData = mergeArray(opts.classData, cData);
// 全選周末
$('.selectWeekend').click(function() {
var y = opts.year;
var m = opts.month;
if($(this).is(':checked')) {
for(var i = firstDayWeek(y, m) - 1; i <= isLeapYear(y, m) + firstDayWeek(y, m) - 2; i++) {
if(new Date(y, m, parseInt(td.eq(i).text())).getDay() == 0 || new Date(y, m, parseInt(td.eq(i).text())).getDay() == 6) {
td.eq(i).addClass('selectDate');
addTotalData(td.eq(i), cData);
}
}
}else {
for(var i = firstDayWeek(y, m) - 1; i <= isLeapYear(y, m) + firstDayWeek(y, m) - 2; i++) {
if(new Date(y, m, parseInt(td.eq(i).text())).getDay() == 0 || new Date(y, m, parseInt(td.eq(i).text())).getDay() == 6) {
td.eq(i).removeClass('selectDate');
removeTotalData(td.eq(i), cData);
}
}
}
});
// 全選當(dāng)月
$('.selectAll').click(function() {
if($(this).is(':checked')) {
td.removeClass('selectDate');
for(var i = firstDayWeek(opts.year, opts.month) - 1; i <= isLeapYear(opts.year, opts.month) + firstDayWeek(opts.year, opts.month) - 2; i++) {
td.eq(i).addClass('selectDate');
addTotalData(td.eq(i), cData);
}
$('.selectWeekend').prop("checked",'true');
}else {
for(var i = firstDayWeek(opts.year, opts.month) - 1; i <= isLeapYear(opts.year, opts.month) + firstDayWeek(opts.year, opts.month) - 2; i++) {
td.eq(i).removeClass('selectDate');
removeTotalData(td.eq(i), cData);
}
$('.selectWeekend').removeAttr("checked");
}
});
// 點選號數(shù)
td.click(function() {
if($(this).children().hasClass('notMonthly')) {
// 這里處理如果點擊了上一個月的號數(shù)的邏輯
}else {
if($(this).hasClass('selectDate')) {
removeTotalData($(this), cData);
$(this).removeClass('selectDate');
}else {
$(this).addClass('selectDate');
addTotalData($(this), cData);
}
}
})
break;
case 2: // 學(xué)生日歷
// 初始化日歷
var initCalender = function(y, m) {
showSelectInfo(sData);
// 復(fù)位checkbox
$('.selectWeekend').removeAttr('checked');
$('.selectAll').removeAttr('checked');
td.removeClass('selectDate');
td.removeClass('selectStuDate');
generateCalendar(y, m);
}
// 用戶參數(shù) stuData 與 歷史sData 并集
var mergeArray = function(arr1, arr2) {
for (var i = 0, j = 0, ci, r = {}, c = []; ci = arr1[i++] || arr2[j++]; ) {
if (r[ci]) continue;
r[ci] = 1;
c.push(ci);
}
return c;
}
cData = opts.classData;
sData = mergeArray(opts.stuData, sData);
// 全選周末
$('.selectWeekend').click(function() {
var y = opts.year;
var m = opts.month;
if($(this).is(':checked')) {
for(var i = firstDayWeek(y, m) - 1; i <= isLeapYear(y, m) + firstDayWeek(y, m) - 2; i++) {
if((new Date(y, m, parseInt(td.eq(i).text())).getDay() == 0 || new Date(y, m, parseInt(td.eq(i).text())).getDay() == 6) && td.eq(i).hasClass('selectDate')) {
td.eq(i).addClass('selectStuDate');
addTotalData(td.eq(i), sData);
}
}
}else {
for(var i = firstDayWeek(y, m) - 1; i <= isLeapYear(y, m) + firstDayWeek(y, m) - 2; i++) {
if(new Date(y, m, parseInt(td.eq(i).text())).getDay() == 0 || new Date(y, m, parseInt(td.eq(i).text())).getDay() == 6) {
if(td.eq(i).hasClass('selectDate')) {
td.eq(i).removeClass('selectStuDate');
removeTotalData(td.eq(i), sData);
}
}
}
}
});
// 全選當(dāng)月
$('.selectAll').click(function() {
if($(this).is(':checked')) {
td.removeClass('selectStuDate');
for(var i = firstDayWeek(opts.year, opts.month) - 1; i <= isLeapYear(opts.year, opts.month) + firstDayWeek(opts.year, opts.month) - 2; i++) {
if(td.eq(i).hasClass('selectDate')) {
td.eq(i).addClass('selectStuDate');
addTotalData(td.eq(i), sData);
}
}
$('.selectWeekend').prop("checked",'true');
}else {
for(var i = firstDayWeek(opts.year, opts.month) - 1; i <= isLeapYear(opts.year, opts.month) + firstDayWeek(opts.year, opts.month) - 2; i++) {
if(td.eq(i).hasClass('selectDate')) {
td.eq(i).removeClass('selectStuDate');
removeTotalData(td.eq(i), sData);
}
}
$('.selectWeekend').removeAttr("checked");
}
});
// 點選號數(shù)
td.click(function() {
if($(this).children().hasClass('notMonthly')) {
// 這里處理如果點擊了上一個月的號數(shù)的邏輯
}else {
if($(this).hasClass('selectDate')) {
if($(this).hasClass('selectStuDate')) {
removeTotalData($(this), sData);
$(this).removeClass('selectStuDate');
}
else {
$(this).addClass('selectStuDate');
addTotalData($(this), sData);
}
}
}
})
break;
}
// 執(zhí)行初始化
initCalender(opts.year, opts.month);
7.回調(diào)函數(shù)
// 回調(diào)函數(shù)
opts.callback(function() {
switch(opts.pattern) {
case 1:
showSelectInfo(cData); // 處理cData及展示數(shù)據(jù)
if(cData.length > 0) { // 返回數(shù)據(jù)
return cData;
}
break;
case 2:
showSelectInfo(sData);
if(sData.length > 0) { // 返回數(shù)據(jù)
return sData;
}
break;
}
});
8.調(diào)用日歷
<script>
/**
* 參數(shù)列表:
* year: 年份 int/string
* month: 月份 int/string 默認(rèn)從0開始 如傳入1將獲得 2月數(shù)據(jù)
* today: 號數(shù) int/string
* classData: 用于接收服務(wù)器傳過來的班級課表數(shù)據(jù) 并在日歷上標(biāo)注 array
* stuData: 用于接收服務(wù)器傳過來的學(xué)生課表數(shù)據(jù) 并在日歷上標(biāo)注 array
* language: 語言 默認(rèn)中文
* patternNum: 切換日歷模式 默認(rèn)1班級課表 可以接收參數(shù)1,2
* callback: 回調(diào)函數(shù) 返回日歷選中的值 返回值類型array
*/
if(parseInt(sessionStorage.editOrAdd)) {
var classData = window.parent.class_tableData; // 獲取服務(wù)器數(shù)據(jù)
var stuData = window.parent.stuData;
}
var patternNum = window.parent.patternNum;
$('.BGOC').BGOCalender({
pattern: patternNum,
classData: classData,
stuData: stuData,
callback: function(data) {
calenderData = data();
$('.calenderTable > tbody > tr > td, .selectAll, .selectWeekend').click(function() {
calenderData = data();
console.log(calenderData);
});
}
});
</script>