移动端旅游报价日历插件

首先声明,此插件为我同事所写,所以此篇博客为转载类型,如有同行需要请标明出处:(作者:lus)
预览效果:


此插件当 arrayJSON 为空时,加载的月份为当前月,月份个数由 index 控制。

HTML:
<!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);



猜你喜欢

转载自blog.csdn.net/bettergg/article/details/80570183