In daily development, most are in dealing with a framework, the passage of time has forgotten the feeling of native JS, personal feel native JS foundation is very important, so recently took advantage of the free time to build a wheel, although in my level made wheels quality or unreliable, but I think it’s used to headphones or good, ha ha!!!!!

So, Let’s begin!

Making: github.com/Zero-jian/p…

The following is the appearance of the calendar, is a little ugly, pay attention to pay attention to, focus on JS part, hee hee!!

On the calendar component implementation ideas

  • Setting default Parameters
  • Check whether node parameters are passed in, otherwise an error is thrown
  • Dynamically creates a horizontal axis that displays the day of the week
  • Dynamically create calendar days
  • Add a little DOM action at the end

Let’s start with the constructor content

constructor(options) {
        letDefaluteOptions = {element: null, // This is the node startOfWeek: 1, strings: {week: n => {let map = {
                        0: 'Sunday',
                        1: 'Monday',
                        2: 'on Tuesday',
                        3: 'on Wednesday',
                        4: 'on Thursday,
                        5: 'on Friday',
                        6: 'on Saturday,}return map[n];
                },
                templateDay: `<li class="currentMonth">
                    <span class="dayLabel">
                        <span class="day"></span>
                        <span class="unit"> day </span> </span> </li> '}, days: {},} // assign the default parameter this.options = object. assign({}, defaluteOptions, options); // create dom this.checkoptions ()._generateTime()._generateweekday ()._generatePrevMonth();Copy the code

Set the value, assign the default parameter and call the method to dynamically create the DOM. I believe that friends can understand this code without pressure.

I wrote the entire wheel in ES6, after all, programmers have to keep up with the trend!!

After the parameter is assigned, the function is called in turn, starting with the this.checkoptions () method to check if the node exists

checkOptions() {// Throw an error directly if the node does not existif(! this.options.element) { throw new Error('element is request');
        }
        return this;
    }
Copy the code

The next step is to get the day and year

It’s a calendar, after all, and it’s important to get the current year, month and day as a reference

_generateTime() {
        letdata = new Date(); / / timeletyear = this.options.days.year = data.getFullYear(); / / yearletmonth = this.options.days.month = data.getMonth() + 1; / / inletday = this.options.days.day = data.getDate(); / / day this. Options. Days. CountDay = 0; / / the calendar is the total number of days 7 * 6 = 42 this. Options. Days. NoMonth = data. GetMonth () + 1; This.options.days.noyear = data.getFullYear(); this.options.days.noyear = data.getFullYear(); // Constant yearreturn this;
    }
Copy the code

Create the week axis

    _generateWeekDay() {
        let {
            startOfWeek,
            strings
        } = this.options;
        let calendar = document.querySelector('.calendar');
        let ol = dom.create(`<ol class="weekdays"></ol>`);
        calendar.appendChild(ol);
        let weekIndex = this.createArray(7, startOfWeek).map((day, i) => {
            let li = dom.create(`<li>${strings.week(i)}</li>`); Ol.appendchild (li); });return this;
    }
Copy the code

Dom.create is a wrapped method that can be created by passing in a template and returned

This.createarray () is also a wrapped method. This creates an array of length 7. Because Monday to Sunday length is 7 ah, then start using map and traversal to create nodes and add document.body!!

Weii weii, go to here, the horizontal axis of the week to create good, the next is the key part, is to create the day of the week calendar, in fact, as long as the master logic is good, but because I am a vegetable chicken, write when also a bit off the pit, so, ha ha, you to my code reference reference good!!

Now comes the point, which is to create the day

Create a calendar day is divided into three parts, the first part is the day of the last month, the second is the day of this month, the third part is the day of the next month, three parts so encapsulate them respectively, 嫑 interact!!

Don’t say much, paste code

// Create the date of last month_generatePrevMonth() {
        let date = this.options.days;
        let year = date.year;
        let month = date.month;
        letbeginWeek = this._getWeekWeek(year, month - 1, 1); // Start weekletcountMonth = this._getMonth(year, month - 1); // Days of last monthlet calendar = document.querySelector('.calendar');
        let ol = dom.create(`<ol class="days"></ol>`);
        let li = document.querySelectorAll('.dayLabel>.day');
        calendar.appendChild(ol);

        date.countDay = 0;
        beginWeek == 0 ? beginWeek += 7 : ' '; // If the month starts on a Sunday, there is a bug, which prevents date.countday += beginWeek; this.createArray(42, this.options.startOfWeek).map((day, i) => {let li = dom.create(this.options.strings.templateDay);
            let span = li.querySelector('.dayLabel>.day');
            if (i < beginWeek) {
                span.textContent = countMonth - beginWeek + 1 + i;
            }
            ol.appendChild(li);
        });

        document.querySelector('h1.date').appendChild(dom.create(`<p data-role="time">${date.year}-${date.month}-${date.day}</p>`));
        this._generateCurrentDay()._generateNextMonth();
    }
Copy the code

Create a day from the beginning to the end, the first is to create the day of last month, logic is to create an array length is 42, because 6 * 7 = 42, array indices of 0 to 41, and then get days last month and this month 1 start of the week, so you can know days placeholder last month, such as May 1 is on Wednesday, so has accounted for three days last month, Then loop through the assignment, thus creating the calendar last month days!!

There is a special case where the first day is Sunday, beginWeek is 0, and the proportion of days in the last month needs to be 7, so you need +7, otherwise there will be a problem

Then create the number of days for the month

By convention, paste code

// Create the current month day_generateCurrentDay() {
        let date = this.options.days;
        letgetWeek = this._getWeekWeek(date.year, date.month - 1, date.day); / / weekletGetMonth = this._getMonth(date.year, date.month) // Number of days in a monthletgetMonthDay = this._getWeekDay(); / / numberlet li = document.querySelectorAll('.dayLabel>.day'); // Create the day of the month moduleletDayIndex = this.createarRay (getMonth, this.options.startofWeek). Map ((day, I) => {dayIndex = this.createarray (getMonth, this.options.startofweek). Map ((day, I) => {dayIndex = this.createarray (getMonth, this.options.startofweek). li[i].textContent = i - date.countDay + 1; // Check whether it is todayif (i == (getMonthDay + date.countDay - 1) && date.noMonth == date.month && date.noYear == date.year) {
                li[i].parentNode.classList.add('today'); }}); date.countDay += getMonth;return this;

    }
Copy the code

GetMonth = 0+data.countDay = 0+data.countDay = 0+data.countDay = 0+data.countDay = 0+data.countDay = 0+data.countDay = 0+data.countDay = 0+data.countDay = 0+data.countDay = 0+data.countDay = 0+data.countDay = 0+data.countDay = 0 That’s about it

Finally, the number of days of the following month

Code code code

// Create the next month's date_generateNextMonth() {
        let date = this.options.days;
        let year = date.year;
        let month = date.month;
        letbeginWeek = this._getWeekWeek(year,month,1); // Start weekletcountMonth = this._getMonth(year,month+1); // Number of days in month of next monthlet li = document.querySelectorAll('.dayLabel>.day'); //data.countDay counts the total number of days last month and this month, This.createarray (42-date.countday, this.options.startOfWeek).map((day,i)=>{ li[date.countDay+i].textContent = i+1; }); }Copy the code

This logic is simple, is (6*7=42) 42 minus the number of days in the last month and the number of days in the current month, the remaining position is the number of days in the next month, so it looks like this!!

Let’s get the wrapped code out, too

/ / the dom. The create () calllet dom = {
    create(html) {
        let template = document.createElement('template');
        template.innerHTML = html;
        returntemplate.content.firstChild; }}Copy the code
CreateArray (length, fill) {this.createarray () calls createArray(length, fill) {let array = Array.apply(null, {
            length: length
        }).map(() => fill);
        returnarray; } // getMonth(year, month) {returnnew Date(year, month, 0).getDate(); } // getweekweek (year, month, day) {returnnew Date(year, month, day).getDay(); } // Get the current month_getWeekDay() {
        return new Date().getDate();
    }
Copy the code

Motion-switching part

It’s relatively easy to switch days here, so I’ll just paste the code so you can see it

// Last monthpreviousMonth() {
        // this.options.days.month -= 1;
        this.changeMonth('prev'); } // Next monthnextMonth() {
        // this.options.days.month += 1;
        this.changeMonth('next'); } // Go back to todayresetMonth() {
        // this._generateTime();
        this.changeMonth('defalut'); } // Dom changeMonth(status) {let date = this.options.days;
        switch(status) {
            case 'prev': {
                --date.month < 1 ?  date.year-- ? date.month = 12 : ' ' : ' ';
                break;
            }

            case 'next': {
                ++date.month > 12 ?  date.year++ ? date.month = 1 : ' ' : ' ';
                break;
            }

            case 'defalut': {
                this._generateTime();
                break; }} // Remove node this._generatecalendar (); // Re-add the node this._generatePrevMonth(); }Copy the code

Call way

    let calendar = new Calendar({
        element: document.querySelector('.calendar'}) // Toggle last month previousMonth.onclick =function() {calendar.previousMonth()} // Switch nextMonth.onclick =function() {calendar.nextmonth ()} // Go back today.onclick =function () {
        calendar.resetMonth()
    }
Copy the code

The entire calendar component uses the this.options.days.month and this.options.days.year parameters to generate calendar data relative to each other, so if you want to switch months, just change these two parameters!!

The whole logic idea is oneself think, so may not calculate is a very good idea, so only for reference!! Ha ha, from the little white not confident…

HMMM, the whole calendar component is probably like this. After writing the whole process, I feel that I have made progress in thinking, but in fact, I think the wheel code can be encapsulated and improved, haha ~~

The function of the wheel is relatively simple, so the rest of the function is waiting for friends to play freely ~~

Well, the first time to write an article, stay up late to write, suddenly inspired, refused to sleep, ha ha, tomorrow work must be dozing, ha ha ~~~

I am a small white, from nearly a year, so what is wrong on the code, please you big god can point out, huh, over ~~