js实现日历效果

news2024/9/22 9:56:39

使用js实现日历效果,主要用到了元素的创建以及添加
对应的方法是document.createElement()document.appendChild()
主要实现思路:

  1. 用div布局把日历的页面框架搭建出来
  2. 依次遍历上月,本月,下月的天数
  3. 切换月份的时候首先清空所有日历元素,再将新的日期添加进去

剩下的就是一些配合js的样式

以下是代码部分:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        h3{
            text-align: center;
        }
        .Calendar{
            width: 420px;
            height: 380px;
            margin: auto;
            background-color: rgb(226,230,236);
        }
        .Calendar>div{
            display: flex;
            height: 54px;
            justify-content: space-around;
        }
        .Calendar>div>div{
            border-radius:50%;
            text-align: center;
            line-height: 52px;
            border: 0.2px solid rgba(200,200,200,0);
            width: 54px;
            height: 54px;
        }
        .Calendar>div:not(:first-child)>div:hover{
            background-color:gray;
        }
        #row1{
            background-color: rgba(153,153,153,0.8);
        }
        #time{
            text-align: center;
            margin-bottom: 10px;
        }
        button{
            border-radius: 10px;
            font-family: 楷体;
            font-weight: bold;
            background-color: rgba(96, 82, 100,0.5);
            border: none;
            color: white;
            padding: 15px 32px;
            text-align: center;
            font-size: 16px;
            cursor: pointer;
        }
        span{
            font-family: 楷体;
            font-weight: bold;
            font-size: 25px;
        }
    </style >
</head>
<body>
    <h3>日历表</h3>
    <div id="time">
        <button onclick="switchLastMonth()">上一月</button>
        <span></span>
        <button onclick="switchNextMonth()">下一月</button>
    </div>
    <div class="Calendar">
        <div id="row1">
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
        <div id="row2">
        </div>
        <div id="row3">
        </div>
        <div id="row4">
        </div>
        <div id="row5">
        </div>
        <div id="row6">
        </div>
        <div id="row7">
        </div>
    </div>
    <script>
        //每月天数
        let fullDaysArr = [31,28,31,30,31,30,31,31,30,31,30,31]
        //当前时间
        let nowDate = new Date()
        let timeSpan = document.getElementsByTagName("span")[0]
        timeSpan.innerText=nowDate.toLocaleDateString()
        //判断今年是否是闰年
        isLeapYear(nowDate.getFullYear())==1?fullDaysArr[1]+=1:fullDaysArr[1]=28
        //上月时间
        let lastDate = new Date(nowDate.getFullYear(),nowDate.getMonth()-1,fullDaysArr[nowDate.getMonth()-1])
        //下月时间
        let nextDate = new Date(nowDate.getFullYear(),nowDate.getMonth()+1,1)
        //每行div的id
        let eleIds = ['row2','row3','row4','row5','row6','row7']
        //eleIds下标
        let j = 0
        //计数总共添加了多少个子元素
        let total = 0
        //计数每行添加了多少个子元素
        let count = 0
        //foreachDate被调用了几次
        let k = 0;
        function updateDate(num) {
            nowDate.setMonth(nowDate.getMonth()+num)
            lastDate=new Date(nowDate.getFullYear(),nowDate.getMonth()-1,fullDaysArr[nowDate.getMonth()-1]) 
            if (nowDate.getMonth()==1) {
                fullDaysArr[1]=28
                isLeapYear(nowDate.getFullYear())==1?fullDaysArr[1]+=1:fullDaysArr[1]=28
            }
            generateCalendar('removeChildren')
            timeSpan.innerText=nowDate.toLocaleDateString()
        }
        //切换到上个月
        function switchLastMonth() {
            updateDate(-1)
        }
        //切换到下个月
        function switchNextMonth() {
            updateDate(1)
        }
        //清空所有日历元素
        function clearCalendar(){
            let eles = getCalendar()
            eles.forEach(e=>{
                e.remove()
            })
        }
        //获取标签元素
        function $(eleName) {
            return document.getElementById(eleName);
        }
        //为每个日历元素添加点击事件
        function addEvent(elements) {
            //记录上一个点击事件的信息
            let temp,color,border
            //为每一个日历时间元素添加点击事件
            for (let index = 0; index < elements.length; index++) {
                    elements[index].addEventListener('click',function(event) {
                        if (temp) {
                            temp.target.style.border = border
                            temp.target.style.color= color
                        }             
                        if (!temp ||temp.target!=event.target) {
                            temp=event,color=event.target.style.color,border=event.target.style.border
                            event.target.style.border="0.2px solid black"
                            event.target.style.color="blue"
                        }
                        
                    })
            }
        }
        //判断是否是闰年
        function isLeapYear(year) {
            return (year%400==0 || (year%4==0 && year%100!=0))?1: 0
        }
        //遍历日期
        function foreachDate(numDay,flag=0) {
            // debugger
            k++   
            if (flag!=-1) {
                for (let i = 1; i <=numDay; i++) {
                    let Div =  document.createElement('div')
                    Div.innerText = i
                    if (i==nowDate.getDate()) {
                        Div.style.background = "rgb(23,115,196)"
                    }
                    if(k==3){
                        Div.style.color="rgb(128, 128, 128, 0.5)"
                    }
                    count++,total++    
                    $(eleIds[j]).appendChild(Div)
                    if (count==7) {
                        j++,count=0 
                    }
                }
            }else{
                for (let i = numDay-1; i >= 0; i--) {
                    let Div =  document.createElement('div')
                    Div.innerText = lastDate.getDate()-i
                    Div.style.color="rgb(128, 128, 128, 0.5)"
                    total++,count++
                    $(eleIds[j]).appendChild(Div)
                    if (count==7) {
                        j++,count=0 
                    }
                }
            }

        }
        //生成日期
        function generateCalendar(mode='appendChild') {
            // debugger
            if (mode=='removeChildren') {
                clearCalendar()
            }
            //上月
            foreachDate(lastDate.getDay()==0?0:lastDate.getDay(),-1)
            //当月
            foreachDate(fullDaysArr[nowDate.getMonth()])
            //下月
            foreachDate(42 - total)
            j=0,total=0,count=0,k=0,n=0
            //获取所有日历时间元素
            let elements = getCalendar()
            //添加点击事件
            addEvent(elements)
        }
        //获取所有日历元素
        function getCalendar(){
            return document.querySelectorAll('div.Calendar>div:not(:first-child)>div')
        }
        window.onload = function() {
            generateCalendar() 
        }
    </script>
</body>
</html>

效果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/659403.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在服务器安装mysql步骤以及mysql数据库连接报错:is not allowed to connect to this mysql server

mysql xxx is not allowed to connect to this MySQL server 服务器上面安装的mysql数据库在本地连接的时候报错&#xff1a;is not allowed to connect to this MySQL server 出现这种情况的原因是因为&#xff1a; mysql数据库只允许自身所在的本机器连接&#xff0c;不允许…

排序算法——直接选择排序

直接选择排序 以升序排序为例 文章目录 直接选择排序算法步骤动图演示实现代码改进算法&#xff08;双指针&#xff09;具体步骤处理特殊情况&#xff1a;实现代码 时间复杂度 算法步骤 方法一&#xff1a;直接交换数组元素 将第一个元素与其他元素进行比较&#xff0c;若其…

初识网络之再看tcp协议

目录 一、tcp协议段格式 二、tcp协议的解包 三、tcp协议的分用 四、TCP可靠性问题 1. 不可靠存在原因 2. 常见的不可靠问题 3. 如何保证可靠性 4. 确认应答机制 5. 序号 五、tcp报头其余字段 1. 16位窗口大小 2. tcp的6个标记位 2.1 SYN 2.2 FIN 2.3 ACK 2.4 P…

【Linux】C语言中多线程的创建、退出、回收、分离

概述 线程是轻量级的进程&#xff08;LWP&#xff1a;light weight process&#xff09;&#xff0c;在 Linux 环境下线程的本质仍是进程。在计算机上运行的程序是一组指令及指令参数的组合&#xff0c;指令按照既定的逻辑控制计算机运行。操作系统会以进程为单位&#xff0c;…

【Spring AOP】面向切面编程

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 1. 什么是Spring AOP&#xff1f; 2. 为什么要…

NFC type 12345 tag介绍

NFC(近场通信)被称为短距离无线技术&#xff0c;是一套通信协议&#xff0c;NFC技术将非接读卡器/Reader、非接标签/Tag和点对点(Peer-to-Peer)数据交换的功能设计融为一体!使电子设备之间能够进行简单、安全的双向交互。为推动NFC技术发展&#xff0c;2004年&#xff0c;诺基亚…

Stable-Diffusion环境搭建

硬件可以采用DELL R7525 搭配L4 或者T4 等等企业级显卡 环境如下&#xff1a; 可以看到有相应的GPU卡信息 esxi 7.u3 信息 设置GPU穿透方式 查看相应的虚拟机参数信息 PCI 设备加载穿透GPU信息 启动uefi 设置相应的参数信息 https://docs.nvidia.com/grid/latest/grid-vgpu-re…

如何检测视频中的绿屏、绿帧问题

今天给项目拷机&#xff0c;发现视频会偶现绿屏&#xff0c;非常偶现&#xff0c;很难复现出来。 由于问题暂时没有定位&#xff0c;只能先表面解决一下&#xff0c;就是过滤掉出现绿屏的帧。 当然&#xff0c;首先要把绿帧检测出来&#xff0c;才能做后续的补救措施。 绿屏、…

电感公式推导

目录 电感的磁感应强度用&#xff1a;B表示 加入磁芯的可以提高磁感应强度&#xff1a;BμNI &#xff08;μ > μ0&#xff09; 磁芯的磁通量用&#xff1a;Φ来表示 一匝线圈感生电动势用&#xff1a;E来表示 在整个电感线圈的里面产生的感生电动势用UL来表示&#xff…

软件测试项目实战,电商项目核心业务测试分析(全覆盖)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 登陆功能怎么测试…

第16章_多版本并发控制

第16章_多版本并发控制 1. 什么是MVCC MVCC(Multiversion Concurrency Control)&#xff0c;多版本并发控制。顾名思义&#xff0c;MVCC是通过数据行的多个版本管理来实现数据库的并发控制。这项技术使得在InnoDB的事务隔离级别下执行一致性读操作有了保证。换言之&#xff0…

chapter9: SpringBoot自定义Starter

尚硅谷SpringBoot顶尖教程 1. 自定义starter介绍 自定义starter从下面两个方面着手&#xff1a; 这个自定义starter的场景需要用到哪些依赖&#xff1f;如何编写自定义starter的自动配置&#xff1f; 查看springboot提供的已有starter组件的自动配置类&#xff0c;基本使用…

NFC Forum Type2 Tag

RC522作为一款NFC读写芯片&#xff0c;性价比还是很高的&#xff0c;因为在项目里需要采用NFC OOB配对&#xff0c;所以需要读取配对方模拟的NFC卡片信息 读取对象采用NRF52832&#xff0c;使用其NFC功能模拟type2 tag&#xff0c;但是读取方式和M1卡不一样&#xff0c;踩了不…

软件测试员不要过于迷信技术,忽视软技能

精于技术对于测试员&#xff0c;乃至技术员本身没毛病&#xff0c;甚至应大加赞赏&#xff0c;在组织中更应像国宝熊猫一样照顾好。然而我们发现&#xff0c;一些精于技术的测试员混的并不好。“纯正”的技术人员就该吃亏&#xff1f;问题到底出现在哪里&#xff1f; 根据我对…

南大通用GBase 8c 多模多态分布式数据库系列二之安装与卸载

目录 一.前言 二. 学习目标 三. 安装流程 四. 配置要求 1. 硬件配置要求 2. 软件配置要求 3. 软件依赖配置 五. 集群规划 1. 物理规划 2. 演示环境配置 六. 安装前环境检查 1. 关闭防火墙 2. 关闭SELINUX 3. 主机名检查、依赖检查 4. Gbase用户配置sudo 七. 配…

科研闭环指南|关于 Review Rebuttal 的二三事

两个月前投稿的论文审稿&#xff08;Review&#xff09;意见快下来了&#xff0c;期间我也是作为审稿人&#xff08;Reviewer&#xff09;完成了4篇工作的审稿工作。回想自己从入学以来也算是审过 10 篇左右的稿子了&#xff0c;也参与过 Review 之后的 Rebuttal 环节。下面我就…

思维决定发展,软件测试人也不例外

最近特别懒&#xff0c;不想码字&#xff0c;原本写作就很差&#xff0c;更是退化严重。社招和校招面试过很多人&#xff0c;从十年前自己还很弱的时候学着面试&#xff0c;到数百次面试积累之后&#xff0c;面对候选人的时候&#xff0c;我的内心依然有些许紧张&#xff0c;非…

《Reinforcement Learning: An Introduction》第5章笔记

Chapter 5 Monte Carlo Methods Monte Carlo 方法不假设拥有完备的环境知识&#xff0c;它仅仅需要经验–从与环境的实际或模拟交互中得到的一系列的状态、动作、和奖励的样本序列。 Monte Carlo方法是基于平均采样回报的来解决强化学习问题的方法。 5.1 Monte Carlo Predic…

NFS服务器

文章目录 NFS服务器NFS的由来与功能什么是NFS(Network File System)什么是RPC(Remote Procedure Call)NFS启动的RPC daemons NFS Server 端的配置所需要的软件NFS的软件结构/etc/exports配置文件的语法与参数 启动NFSRPC服务的注册状况怎么查看(rpcinfo) NFS的连接查看showmoun…

认识服务器

1、查看操作系统的信息 CentOS 输入&#xff1a;cat /etc/os-release 字段含义解释NAME操作系统名称CentOS LinuxVERSION操作系统版本7 (Core)ID操作系统标识centosID_LIKE相关操作系统标识rhel fedoraVERSION_ID操作系统版本号7PRETTY_NAME可读性较好的操作系统名称CentOS L…