马黑黑 发表于 2023-12-29 12:25

练手:写一个JS日历

<style>
#mydiv {
        margin: 50px auto;
        padding: 6px;
        width: fit-content;
        border: 4px solid rgba(0,0,0,.15);
        border-radius: 6px;
        background: rgba(100,100,100,.6);
        box-shadow: 4px 4px 16px rgba(0,0,0,.25);
}
#rlTop {
        display: flex;
        gap: 6px;
        background: #ccc;
        padding: 10px;
        border-radius: 10px 10px 0 0;
}
#today {
        text-align: right;
        cursor: pointer;
        user-select: none;
}
#rili {
        width: 280px;
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        background: #eee;
        border-radius: 0 0 10px 10px;
}
.tbox {
        width: 40px;
        height: 40px;
        text-align: center;
        font: normal 16px/40px sans-serif;
}

</style>

<div id="mydiv">
        <div id="rlTop">
                <select id="sYear"></select>
                <select id="sMonth"></select>
                <span id="today" title="今日日历">今日</span>
        </div>
        <div id="rili"></div>
</div>

<script>
let thisYear = new Date().getFullYear();
let thisMonth = new Date().getMonth();
let thisDay = new Date().getDate();
let m1stDay = (y,m) => new Date(y, m).getDay();
let mAllDays = (y,m) => new Date(y, m + 1, 0).getDate();

let calendar = (year,month) => {
        let ar = '日一二三四五六'.split('').map(c => `<div class="tbox">${c}</div>`);
        let output = ar.join('');
        let d = new Date(year,month);
        let y = d.getFullYear(), m = d.getMonth();
        let alldays = mAllDays(y,m);
        let firstday = m1stDay(y,m);
        Array.from({length: alldays + firstday}).forEach((item,key) => {
                let idx = key < firstday ? '' : (key - firstday + 1);
                if(idx == thisDay && month == thisMonth && year == thisYear)
                        idx = `<span style="color:red">${idx}</span>`;
                output += `<div class="tbox">${idx}</div>`;
        });
        rili.innerHTML = output;
};

let mkYear = () => {
        let ar = [...new Array(10).keys()].map(item => item + 2018);
        ar.forEach((y,k) => {
                let selected = y == new Date().getFullYear() ? 'selected' : '';
                sYear.innerHTML += `<option ${selected} value="${y}">${y}年</option>`;
        });
};

let mkMonth = () => {
        Array.from({length: 12}).forEach((m,k) => {
                let selected = k === new Date().getMonth() ? 'selected' : '';
                sMonth.innerHTML += `<option ${selected} value="${k}">${k + 1}月</option>`;
        });
};

sYear.onchange = sMonth.onchange = () => calendar(sYear.value,sMonth.value);

today.onclick = () => {
        sYear.value = thisYear;
        sMonth.value = thisMonth;
        calendar(thisYear,thisMonth);
};

calendar(thisYear,thisMonth);
mkYear();
mkMonth();

</script>

马黑黑 发表于 2023-12-29 12:26

只是个练手小作品,全部代码如下:<style>
#mydiv {
        margin: 50px auto;
        padding: 6px;
        width: fit-content;
        border: 4px solid rgba(0,0,0,.15);
        border-radius: 6px;
        background: rgba(100,100,100,.6);
        box-shadow: 4px 4px 16px rgba(0,0,0,.25);
}
#rlTop {
        display: flex;
        gap: 6px;
        background: #ccc;
        padding: 10px;
        border-radius: 10px 10px 0 0;
}
#today {
        text-align: right;
        cursor: pointer;
        user-select: none;
}
#rili {
        width: 280px;
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        background: #eee;
        border-radius: 0 0 10px 10px;
}
.tbox {
        width: 40px;
        height: 40px;
        text-align: center;
        font: normal 16px/40px sans-serif;
}

</style>

<div id="mydiv">
        <div id="rlTop">
                <select id="sYear"></select>
                <select id="sMonth"></select>
                <span id="today" title="今日日历">今日</span>
        </div>
        <div id="rili"></div>
</div>

<script>
let thisYear = new Date().getFullYear();
let thisMonth = new Date().getMonth();
let thisDay = new Date().getDate();
let m1stDay = (y,m) => new Date(y, m).getDay();
let mAllDays = (y,m) => new Date(y, m + 1, 0).getDate();

let calendar = (year,month) => {
        let ar = '日一二三四五六'.split('').map(c => `<div class="tbox">${c}</div>`);
        let output = ar.join('');
        let d = new Date(year,month);
        let y = d.getFullYear(), m = d.getMonth();
        let alldays = mAllDays(y,m);
        let firstday = m1stDay(y,m);
        Array.from({length: alldays + firstday}).forEach((item,key) => {
                let idx = key < firstday ? '' : (key - firstday + 1);
                if(idx == thisDay && month == thisMonth && year == thisYear)
                        idx = `<span style="color:red">${idx}</span>`;
                output += `<div class="tbox">${idx}</div>`;
        });
        rili.innerHTML = output;
};

let mkYear = () => {
        let ar = [...new Array(10).keys()].map(item => item + 2018);
        ar.forEach((y,k) => {
                let selected = y == new Date().getFullYear() ? 'selected' : '';
                sYear.innerHTML += `<option ${selected} value="${y}">${y}年</option>`;
        });
};

let mkMonth = () => {
        Array.from({length: 12}).forEach((m,k) => {
                let selected = k === new Date().getMonth() ? 'selected' : '';
                sMonth.innerHTML += `<option ${selected} value="${k}">${k + 1}月</option>`;
        });
};

sYear.onchange = sMonth.onchange = () => calendar(sYear.value,sMonth.value);

today.onclick = () => {
        sYear.value = thisYear;
        sMonth.value = thisMonth;
        calendar(thisYear,thisMonth);
};

calendar(thisYear,thisMonth);
mkYear();
mkMonth();

</script>

红影 发表于 2023-12-29 12:47

这个随便输入年份和月,就能知道那一天是周几了,厉害{:4_199:}

红影 发表于 2023-12-29 12:49

刚才没改月份,输入2024年,发现是1号是周日,然后才发现忘了改月份,1月的1号是周一的{:4_173:}

红影 发表于 2023-12-29 12:50

这个日历好,自己人做的呢,比别的都珍贵{:4_199:}

梦油 发表于 2023-12-29 17:17

这可太实用了。

醉美水芙蓉 发表于 2023-12-29 17:18

马黑黑 发表于 2023-12-29 17:20

醉美水芙蓉 发表于 2023-12-29 17:18
老师这个日历很牛!

没啥功能,且当练习

马黑黑 发表于 2023-12-29 17:24

红影 发表于 2023-12-29 12:47
这个随便输入年份和月,就能知道那一天是周几了,厉害

这是日历最基本的功能。里面的算法仰赖JS的date对象,可以很容易算出一个月头一天星期几、每个月的天数。我不记得我用过的什么语言,计算二月份的天数要自己设计算法,JS可以不用。

马黑黑 发表于 2023-12-29 17:24

梦油 发表于 2023-12-29 17:17
这可太实用了。

现在日历多了去,且功能都丰富、完备,这个知识练习而已

侃大山 发表于 2023-12-29 18:27

很实用,外观也好{:4_204:}

马黑黑 发表于 2023-12-29 19:27

侃大山 发表于 2023-12-29 18:27
很实用,外观也好

感谢支持

红影 发表于 2023-12-29 19:34

马黑黑 发表于 2023-12-29 17:24
这是日历最基本的功能。里面的算法仰赖JS的date对象,可以很容易算出一个月头一天星期几、每个月的天数。 ...

JS的这个功能太棒了{:4_187:}

马黑黑 发表于 2023-12-29 22:31

红影 发表于 2023-12-29 19:34
JS的这个功能太棒了

它封装的 date 对象却是挺好,然后使用者只要掌握一些原理和算法,就不必太费劲就可以实现很多功能。

红影 发表于 2023-12-29 23:14

马黑黑 发表于 2023-12-29 22:31
它封装的 date 对象却是挺好,然后使用者只要掌握一些原理和算法,就不必太费劲就可以实现很多功能。

但是能弄得这么好看也不容易呢{:4_187:}

马黑黑 发表于 2023-12-30 12:59

红影 发表于 2023-12-29 23:14
但是能弄得这么好看也不容易呢

那是CSS的功劳

红影 发表于 2023-12-30 13:16

马黑黑 发表于 2023-12-30 12:59
那是CSS的功劳

更是黑黑的功劳{:4_199:}

梦油 发表于 2023-12-30 14:25

马黑黑 发表于 2023-12-29 17:24
现在日历多了去,且功能都丰富、完备,这个知识练习而已

看着你熟练的代码技巧真是很羡慕。

小辣椒 发表于 2023-12-30 15:11

高手的,黑科技就是这样的,样样都可以信手拈来{:4_199:}

马黑黑 发表于 2023-12-31 10:36

小辣椒 发表于 2023-12-30 15:11
高手的,黑科技就是这样的,样样都可以信手拈来

{:4_191:}
页: [1] 2 3 4
查看完整版本: 练手:写一个JS日历