js原生(包含es6语法) - 模拟Mac 日历

闲时练练技术,主要关注代码可读性与优雅 ?
html部分按照上中下布局来写,没什么难度,就不解释了。。。

<body>
    <!-- Mac日历模拟 -->
    <div id="calendar">
        <div class="bar">
            <div class="btn y-center">
                <span class="orange"></span>
                <span class="yellow"></span>
                <span class="green"></span>
            </div>
            <div class="bar-box y-center calen">
                <span>日历</span>
            </div>
            <div class="bar-box y-center add">
                <svg t="1565941276742" class="icon add-svg" viewBox="0 0 1024 1024" version="1.1"
                    xmlns="http://www.w3.org/2000/svg" p-id="1987" width="15" height="15">
                    <path
                        d="M938.116981 485.111606h-409.793201V75.319429c0-13.715373-11.120268-24.835641-24.835641-24.835641-13.715373 0-24.835641 11.120268-24.835641 24.835641V485.111606H68.859297c-13.715373 0-24.835641 11.120268-24.835641 24.835642s11.120268 24.835641 24.835641 24.835641h409.792177v409.7932c0 13.715373 11.120268 24.835641 24.835642 24.835642 13.715373 0 24.835641-11.120268 24.835641-24.835642V534.783913h409.792177c13.715373 0 24.835641-11.120268 24.835642-24.835642S951.832354 485.111606 938.116981 485.111606z"
                        p-id="1988" fill="#4e4d4e"></path>
                </svg>
            </div>
            <div class="bar-box y-center bar-menu">
                <div><span></span></div>
                <div><span></span></div>
                <div class="current-menu"><span></span></div>
                <div class="clear-border-right"><span></span></div>
            </div>
            <input type="search" class="bar-box y-center search">
            <div class="bar-box y-center search">
                <div class="s-text">
                    <svg t="1565948270747" class="icon" viewBox="0 0 1024 1024" version="1.1"
                        xmlns="http://www.w3.org/2000/svg" p-id="2959" width="16" height="16">
                        <path
                            d="M963.584 934.912L711.68 683.008C772.096 615.424 808.96 527.36 808.96 430.08 808.96 221.184 638.976 51.2 430.08 51.2S51.2 221.184 51.2 430.08s169.984 378.88 378.88 378.88c97.28 0 185.344-36.864 252.928-97.28l251.904 251.904c4.096 4.096 9.216 6.144 14.336 6.144s10.24-2.048 14.336-6.144c8.192-8.192 8.192-20.48 0-28.672zM430.08 768C243.712 768 92.16 616.448 92.16 430.08S243.712 92.16 430.08 92.16s337.92 151.552 337.92 337.92-151.552 337.92-337.92 337.92z"
                            p-id="2960"></path>
                    </svg>
                    <span>搜索</span>
                </div>
            </div>
        </div>
        <div class="weeks">
            <div class="week-cur">
            </div>
            <div class="week-texts">
                
            </div>
        </div>
        <div class="mains">
        </div>
    </div>
    </div>
    <script src="calendar.js"></script>
</body>

下面是重头戏⚠️,js部分。中、下两部分的内容都是通过js渲染的。
开始写js前要先做几个准备

1. 星期
	const weeks = "日一二三四五六".split('')
2. 每个月有几天
	let monthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
3. 每个月的第一天是星期几
	monthOneWeekend = new Date(year, month, 1).getDay()

下面开始渲染

// 渲染星期
const weeks = "日一二三四五六".split('')
let weekTexts = document.querySelector('#calendar .weeks .week-texts');
let weeksDom = []
for (let w of weeks.values()) { // 使用es6 的 values()遍历,直接获取值,比遍历键然后再取值节省性能
    weeksDom.push("<div>周" + w + "</div>")
}
weekTexts.innerHTML = weeksDom.join('')
// 填充主体数字
function drawData(qdate) {
    if (!qdate) qdate = QDate

    // 渲染今天年月
    let weekCur = document.querySelector('#calendar .weeks .week-cur');
    let weekCurDom = '<span class="cur">' + qdate.year + '年' + (qdate.month + 1) + '月</span><div class="cur-box"><div id="prevMonth" οnclick=btnEvent("prevMonth")> < </div><div id="now" οnclick=btnEvent("now")>今天</div><div id="laterMonth" οnclick=btnEvent("laterMonth")> > </div></div>'
    weekCur.innerHTML = weekCurDom

    // 前面空几天
    let year = qdate.year,
        month = qdate.month,
        day = qdate.day,
        monthOneWeekend = new Date(year, month, 1).getDay(),
        monthday = monthDays[month]
    let prevSpace = monthOneWeekend === 7 ? 0 : monthOneWeekend
    // 判断闰年,更改闰年 2 月的天数
    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
        monthDays[1] = 29
    }
    // 渲染主体数据 
    // 将框和文字一起渲染?框和文字分开渲染?
    // 选前者
    let mains = document.querySelector('.mains')
    mains.innerHTML = ""
    let dayDom = [],
        dayClaz = 'day'

    function claz(claz, i) {
        return i != 0 && i % 7 == 0 ? dayClaz + ' clear-border-right' : dayClaz // 清除边框
    }

    function numClaz(currentDay) { // 判断是否是今天
        return year === (currentDate().year) && month === (currentDate().month) && currentDay === (currentDate().day) ? "current-num" : ""
    }
    // 空白
    for (let i = 0; i < prevSpace; i++) {
        clazs = claz(claz, i + 1)
        dayDom.push('<div class="' + clazs + '"></div>')
    }
    // 主体
    for (let i = 1; i < monthday + 1; i++) {
        clazs = claz(claz, i + prevSpace)
        dayDom.push('<div class="' + clazs + '"><div><span class="num ' + numClaz(i) + '">' + i + '</span><span>日</span></div></div>')
        // dayDom.push('<div class="' + clazs + '">'+i+'</div>')
    }
    // 剩余空白
    for (let i = 0; i < (42 - monthday - prevSpace); i++) {
        clazs = claz(claz, i + monthday + prevSpace + 1)
        dayDom.push('<div class="' + clazs + '"></div>')
    }

    mains.innerHTML = dayDom.join('')
}

在全局中维护了一个日期对象

let currentDate = function (date) {
    if (date == undefined || date == null) date = new Date()
    return {
        year: date.getFullYear(),
        month: date.getMonth(),
        day: date.getDate()
    }
}

// 维护一个全局的年月对象,初始值为今天
let QDate = {
    year: currentDate().year,
    month: currentDate().month,
    day: currentDate().day,
    prevMonth: function () {
        if (this.month === 0) {
            this.year--;
            this.month = 11;
        } else {
            this.month--;
        }
    },
    laterMonth: function () {
        if (this.month === 11) {
            this.year++;
            this.month = 0;
        } else {
            this.month++
        }
    },
    current: function () {
        this.year = currentDate().year,
            this.month = currentDate().month,
            this.day = currentDate().day
    }
}

完成效果图长这样 ?
项目github地址: https://github.com/yseventeen/Mac-calendar

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值