首先声明,此插件为我同事所写,所以此篇博客为转载类型,如有同行需要请标明出处:(作者:lus)
预览效果:
HTML:
预览效果:
此插件当 arrayJSON 为空时,加载的月份为当前月,月份个数由 index 控制。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/> <meta name="format-detection" content="telephone=no,email=no,date=no,address=no"> <link rel="stylesheet" href="common.css"> <style> /* 没有 common.css 文件,添加以下注释 css*/ /* html {font-size:62.5%;} body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td {margin:0; padding:0;} .fs10 {font-size:1.0rem;} */ .ZYCalender .dateZone{ width: 100%; margin: auto; background: #f5f5f5; color:#666; position: -webkit-sticky; position: sticky; top: 0; z-index: 999; } .ZYCalender .tbody{ background: #f3f3f3; padding-bottom: 4.5rem; } .ZYCalender .tbody td{ background: #fff; text-align: center; height: 4.4rem; font-size: 1.4rem; color: #666; width: 14.2%; border: 2px solid #fff; } .ZYCalender .tbody td .con{ height: 4.4rem; font-size: 1.4rem; } .ZYCalender .tbody td p{ line-height: 14px; } .ZYCalender .tbody .sel{ background: #cab970; border-radius: 5px; } .ZYCalender .tbody tr{ vertical-align: top; } .ZYCalender .dateZone td{ background: #f5f5f5; width: 14.2%; font-size: 1.4rem; text-align: center; height: 45px; } .ZYCalender .dateZone .colo{ color: #ffd101; } .ZYCalender .dateTable{ width: 100%; margin: auto; } .ZYCalender .tbody .itemMonth{ margin-bottom: 10px; background: #fff; padding: 10px 5px; } .ZYCalender .tbody .month{ width: 100%; text-align: center; padding: 8px 0; font-size: 1.6rem; } .ZYCalender .hover{ font-size: 1.2rem; display: inline-block; width: 60%; background: #ffd101; color: #ba0003; text-align: center; border-radius: 5px; } .confirm{ width: 100%; height: 4.0rem; background: #eb8300; position: fixed; bottom: 0; z-index: 999; text-align: center; font-size: 1.8rem; color: #fff; line-height: 4.0rem; } </style> </head> <body> <div class="ZYCalender"></div> <div class="confirm">提交</div> </body> <script src="calender.js"></script> <script> var arrayJSON = [ { id: '0', date: '2017-12-29', price: '¥ 123', number: '>9人' }, { id: '1', date: '2017-12-30', price: '¥ 123', number: '>9人' }, { id: '2', date: '2017-12-31', price: '¥ 123', number: '>9人' }, { id: '3', date: '2018-02-01', price: '¥ 123', number: '>9人' }, { id: '4', date: '2018-02-02', price: '¥ 123', number: '>9人' }, { id: '5', date: '2018-02-03', price: '¥ 123', number: '>9人' }, { id: '6', date: '2018-02-04', price: '¥ 123', number: '>9人' }, { id: '7', date: '2018-02-05', price: '¥ 123', number: '>9人' }, { id: '8', date: '2018-02-06', price: '¥ 123', number: '>9人' }, { id: '9', date: '2018-02-07', price: '¥ 123', number: '>9人' }, { id: '10', date: '2018-02-08', price: '¥ 123', number: '>9人' }, { id: '11', date: '2018-02-09', price: '¥ 123', number: '>9人' } ]; new ZYCalender({ element: document.querySelector('.ZYCalender'), color: '#fff', arrayJSON: arrayJSON, confirmBtn: document.querySelector('.confirm'), callback: function (e) { console.log(e) } }) </script> </html>JS:
/* * by lus * luszy.com * */ (function (window, undefined) { "use strict"; var ZYCalender = function(params){ this.extend(this.params, params); this.init(); }; ZYCalender.prototype = { params: { element: false, index : 4, // 展示的月份个数 bgColor : "#f5f5f5", // 开始结束中间颜色 color: '#ffd101', // 选中的文字颜色 arrayJSON: '', confirmBtn: '', callback: function () { } }, init: function () { var self = this, ii, tHTML, currentYear, currentMonth, setCurrentDate, firstDay, month, DaysInMonth = [], Ntd, Ntr, createTd, anyTd, p; self.element = this.params.element; self.index = this.params.index; self.confirm = this.params.confirmBtn; self.arrayJSON = this.params.arrayJSON; self.dayDate = []; self.dayDateWeek = []; if(!this.params.element || this.params.element.nodeType !== 1) return; var html = "<table class='dateZone border-b' data-fixed=''>" + "<tr>" + "<td class='colo'>日</td>" + "<td>一</td>" + "<td>二</td>" + "<td>三</td>" + "<td>四</td>" + "<td>五</td>" + "<td class='colo'>六</td>" + "</tr>" + "</table>" + "<div class='tbody'></div>"; self.element.innerHTML = html; if(self.arrayJSON){ var arr = [], index; self.arrayJSON.forEach(function (element, index) { arr.push(element.date.substring(0, element.date.length - 3)); }); index = self.removeRepeatArray(arr); for(var i = 0; i < index.length; i++){ ii = i; tHTML = "<div class='itemMonth border-b'>" + "<p class='month'></p>" + "<table class='table' style='width: 100%;position: relative'>" + "<tbody class='dateTable'></tbody>" + "</table>" + "</div>"; self.element.querySelector('.tbody').insertAdjacentHTML('beforeEnd', tHTML); currentYear = index[ii].substring(0, 4); currentMonth = index[ii].substring(5, 7); setCurrentDate = new Date(currentYear, currentMonth - 1, 1); firstDay = setCurrentDate.getDay(); self.element.querySelectorAll('.month')[ii].innerHTML = currentYear + '年' + currentMonth + '月'; if (self.isLeapYear(currentYear)) { DaysInMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; } else { DaysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; } Ntd = firstDay + DaysInMonth[currentMonth - 1]; Ntr = Math.ceil(Ntd / 7); for (var j = 0; j < Ntr; j++) { self.element.querySelectorAll('.dateTable')[ii].insertAdjacentHTML('beforeEnd', '<tr></tr>'); } createTd = self.element.querySelectorAll('.dateTable')[ii].querySelectorAll('tr'); createTd.forEach(function(element, index) { for (var m = 0; m < 7; m++) { element.insertAdjacentHTML('beforeEnd', '<td></td>') } }); anyTd = self.element.querySelectorAll('.dateTable')[ii].querySelectorAll('td'); for (var n = 0; n < DaysInMonth[currentMonth - 1]; n++) { p = firstDay++; anyTd[p].innerHTML = '<div class="con">'+ (n + 1) +'</div>'; self.arrayJSON.forEach(function (element) { if( currentMonth === element.date.substring(5, 7) && currentYear === element.date.substring(0, 4) && n + 1 === parseInt(element.date.substring(8, 10)) ){ anyTd[p].querySelector('.con').insertAdjacentHTML('beforeEnd', '<p class="fs10" data-id="'+ element.id +'" data-price="'+ element.price +'">' + '<span>' + element.price + '</span>'+ '<br>' + '<span>' + element.number+ '</span>' + '</p>'); anyTd[p].querySelector('.con').classList.add('border') } }); } } } else { for(var i = 0; i < self.index; i++){ ii = i; tHTML = "<div class='itemMonth border-b'>" + "<p class='month'></p>" + "<table class='table' style='width: 100%;position: relative'>" + "<tbody class='dateTable'></tbody>" + "</table>" + "</div>"; self.element.querySelector('.tbody').insertAdjacentHTML('beforeEnd', tHTML); var currentDate = new Date(); currentDate.setMonth(currentDate.getMonth() + ii); currentYear = currentDate.getFullYear(); currentMonth = currentDate.getMonth(); setCurrentDate = new Date(currentYear, currentMonth, 1); firstDay = setCurrentDate.getDay(); month = currentMonth + 1; if (month < 10) { self.element.querySelectorAll('.month')[ii].innerHTML = currentYear + '年' + '0' + month + '月'; } else { self.element.querySelectorAll('.month')[ii].innerHTML = currentYear + '年' + month + '月'; } if (self.isLeapYear(currentYear)) { DaysInMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; } else { DaysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; } Ntd = firstDay + DaysInMonth[currentMonth]; Ntr = Math.ceil(Ntd / 7); for (var j = 0; j < Ntr; j++) { self.element.querySelectorAll('.dateTable')[ii].insertAdjacentHTML('beforeEnd', '<tr></tr>'); } createTd = self.element.querySelectorAll('.dateTable')[ii].querySelectorAll('tr'); createTd.forEach(function(element, index) { for (var m = 0; m < 7; m++) { element.insertAdjacentHTML('beforeEnd', '<td></td>') } }); anyTd = self.element.querySelectorAll('.dateTable')[ii].querySelectorAll('td'); for (var n = 0; n < DaysInMonth[currentMonth]; n++) { anyTd[firstDay++].innerText = (n + 1); } } } self.initSelect(); self.addEvent(self.confirm, 'click', function (event) { event.preventDefault(); self.date = ''; self.price = ''; self.id = ''; self.day = []; var sels = self.element.querySelectorAll('.sel'); for(var u = 0; u < sels.length; u++){ var id = sels[u].querySelector('p') ? sels[u].querySelector('p').getAttribute('data-id') : ''; var day = sels[u].innerText.substring(0, 2) < 10 ? '0' + sels[u].innerText.substring(0, 2) : sels[u].innerText.substring(0, 2); var startDayArrays = sels[u].offsetParent.previousSibling.innerText.split(''); var startDayArrayYear = [], startDayArrayMonth = [], startDayYear = "", startDayMonth = "", date = '', price = ''; for (var g = 0; g < 4; g++) { startDayArrayYear.push(startDayArrays[g]) } startDayYear = startDayArrayYear.join(''); for (var f = 5; f < 7; f++) { startDayArrayMonth.push(startDayArrays[f]) } startDayMonth = startDayArrayMonth.join(''); date = startDayYear + '-' + startDayMonth + '-' + day; price = sels[u].querySelector('p') ? sels[u].querySelector('p').getAttribute('data-price') : ''; if(!self.arrayJSON){ self.day.push(date); } else { self.price = price; self.date = date; self.id = id; } } if(!self.arrayJSON) { if (!self.day) return; } else { if (!self.date) return; } self.callback(); }); }, initSelect: function () { var self = this; var strDays = new Date().getDate(); var arry = []; var arry1 = []; self.element.querySelector('.tbody').querySelectorAll('td').forEach(function(element, index) { if (element.innerText !== '') { arry.push(element); } }); if(!self.arrayJSON){ for (var i = 0; i < strDays - 1; i++) { arry[i].style.color = '#ccc'; } for (var i = strDays - 1; i < arry.length; i++) { arry1.push(arry[i]) } self.selectDate(arry1) } else { self.selectDate(arry) } }, isLeapYear: function(year) { return (year % 4 === 0) && (year % 100 !== 0 || year % 400 === 0); }, selectDate: function(arry1) { var self = this; self.bgColor = self.params.bgColor; self.color = self.params.color; self.element = self.params.element; for(var i = 0; i < arry1.length; i++){ (function(j){ arry1[j].onclick = function () { if(self.arrayJSON){ arry1.forEach(function (element, index) { element.classList.remove('sel'); element.style.color = ''; }); arry1[j].classList.add('sel'); arry1[j].style.color = self.color; } else { if(arry1[j].classList.contains('sel')){ arry1[j].style.background = ''; arry1[j].style.color = ''; arry1[j].classList.remove('sel'); } else { arry1[j].setAttribute('data-type', 'start'); arry1[j].classList.add('sel'); } self.checkColor(self.color, self.bgColor); } } })(i) } }, callback: function() { var self = this; if (self.params.callback && typeof (self.params.callback) === "function") { self.params.callback({ date: self.date || '', price: self.price || '', id: self.id || '', day: self.day || '' }); } }, checkColor: function(color, bgColor) { var self = this; var sel = self.element.querySelectorAll('.sel'); for (var i = 0; i < sel.length; i++) { sel[i].style.background = bgColor; sel[i].style.color = color; } }, removeRepeatArray: function (arr) { return arr.filter(function (item, index, self) { return self.indexOf(item) === index; }); }, addEvent: function (elm, type, fn) { if (window.attachEvent) { elm.attachEvent("on" + type, fn) } else if (window.addEventListener) { elm.addEventListener(type, fn, false); } else { elm["on" + type] = fn; } }, extend: function (a, b) { for (var key in b) { if (b.hasOwnProperty(key)) { a[key] = b[key]; } } return a; } }; window.ZYCalender = ZYCalender; })(window);