其他分享
首页 > 其他分享> > 原生JS学习之秒表、日历

原生JS学习之秒表、日历

作者:互联网

 

  Tips:涉及知识点:Date   setInterval    DOM   

 

秒表

 

效果图:

 

 

  简单构造出草图

 

 

 

 Html代码

 

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>时间Demo</title>
 5     <meta charset="utf-8">
 6     <link rel="stylesheet" type="text/css" href="css/time.css">
 7 </head>
 8 <body>
 9     <div align="center">
10         <!-- 导航栏     -->
11         <div id = "nav">
12             <a href="#">闹钟</a>&nbsp;
13             <a href="#">计时器</a>&nbsp;
14             <a href="#" style="color:white">秒表</a>
15         </div>
16 
17         <!-- 时钟 -->
18         <div id = "timer" align="center">
19             <br>
20             <span id = "title">Timer</span><br>
21             <span id = "tips" class = "timer">&nbsp;&nbsp;&nbsp;&nbsp;M&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S&nbsp;</span><br>
22             <span id = "tim" class = "timer">00:00</span><br>
23             <span id = "s" class = "timer">00</span>
24         </div>
25         <!-- 底部按钮 -->
26         <div id = "footer">
27             <table>
28                 <tr>
29                     <td><button onclick = "start()" id = "start">开&nbsp;始</button></td>
30                     <td><button onclick = "stop()">暂&nbsp;停</button></td>
31                     <td><button onclick = "re()">复&nbsp;位</button></td>
32                 </tr>
33             </table>
34         </div>
35     </div>
36     <script type="text/javascript" src = "js/time.js"></script>
37 </body>
38 </html>

 

中间使用了大量的&nbsp;   <br>     是因为我目前不太会调这个细节,只好拿这些来补位

 

CSS代码

 

 1         body{
 2             background: black;
 3         }
 4         a{
 5             color:gray;
 6             text-decoration:none;
 7             font-size:larger;
 8         }
 9         #nav{
10             border-bottom:1px solid orange;
11             width: 50%;
12             text-align: left;
13             padding-bottom: 10px;
14         }
15         #timer{
16             margin-top: 20px;
17             margin-bottom: 20px;
18             height: 250px;
19             width: 250px;
20             border-radius:50%;
21             border:5px dashed skyblue;
22             text-align: center;
23 
24         }
25         #title{
26             color:gray;
27             font-size:xxx-large;
28         }
29         #tim{
30             font-size:xxx-large;
31         }
32         #tips{
33             font-size: x-large;
34         }
35         .timer{
36             color:white;
37         }
38         #s{
39             font-size:xx-large;
40         }
41         button{
42             background: orange;
43             color:gray;
44             width: 80px;
45             height: 30px;
46             border: none;
47             outline: none;
48             font-size:large; 
49         }
50         button:hover{
51             color:black;
52         }
53         table{
54             width: 600px;
55             border-collapse: collapse;
56             border-spacing: 0;
57             table-layout: fixed;
58             text-align:center;
59         

 

 

 

除了常见的样式,还加了一些现查的

比如

  实现a标签去除原有样式:  text-decoration:none;

  按钮的边框去除

                 border: none;

       outline: none;

 

JS实现

 

思路分析:

  我第一下想象到的是Js的计时器,setInterval(),然后每10ms执行一次,然后是纯逻辑判断,不用任何内置对象。后来发现,如果是这样,那么会很复杂,判断条件也很多。

  后来想到了Date对象,可以通过点击时与当前时间做差值运算,这样就少了很多边界条件的判断。

 

首先是取得节点,clc是用来获得计时器的标志位,方便后来停止

1 var time = document.getElementById("tim");
2 var ss = document.getElementById("s");
3 var clc = null;

 

 

开始按钮点击时进行的操作:

 1 function start(){
 2     clearInterval(clc);//防止点击两次之后,无法停止计时器的问题
 3     let time2=new Date().getTime();
 4     clc = setInterval(function(){ 
 5         let times = new Date().getTime() - time2;
 6         let minutes=Math.floor(times/60000);
 7         let seconds=Math.floor((times-minutes*60000)/1000);
 8         let ms=Math.floor((times-minutes*60000-seconds*1000)/10);
 9         time.innerText = (minutes<10 ? "0" +minutes : minutes)+":"
10                      +(seconds<10 ? "0"+seconds :seconds);
11          ss.innerText = ms<10?"0"+ms:ms;
12     }, 10);
13 }

 

 

new Date().getTime()    使用来获取当前时间到1970年1月1日的毫秒数

通过取余,取整,补零等简单的操作,就可以得到时间,然后每10毫秒渲染在页面上一次。

 

暂停和复位JS

1 function stop(){
2     clearInterval(clc);
3 }
4 
5 function re(){
6     time.innerText = "00:00";
7     ss.innerText = "00";
8 }

 

 

到这里,功能基本实现,但是留下了一个疑问

 

    秒表计时是按照点击开始的时间和每过10ms的时间计算得到的,那么再此点击开始,时间就会从0开。

    但所给的最终效果只是一个图片,无法判断接下来要实现的功能。

    如果扩展的话,可以加上一个参数,就是按下暂停的时间(页面上显示的)。

 

 

日历

 

 

效果图

 

 

 

 

这个结构也很明显,所以直接上手

 

Html代码

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4     <meta charset="utf-8">
  5     <title>日历Demo</title>
  6     <link rel="stylesheet" type="text/css" href="css/date.css">
  7 </head>
  8 <body>
  9     <div id = "main" align="center">
 10         <!-- 标题 -->
 11         <div id = "title">
 12             <h2>模拟日历</h2>
 13         </div>
 14 
 15         <!-- 输入框 -->
 16         <div >
 17             <span>年</span>
 18             <input type="text" id = "year">
 19             <span>月</span>
 20             <input type="text" id = "month">
 21             <span>&nbsp;</span>
 22             <input type="button" id = "btn" value="生&nbsp;成" onclick = "fun()">
 23         </div>
 24 
 25         <!-- 日历 -->
 26         <div id = "calendar">
 27 
 28             <div id = "date">
 29                 <span id = date2></span>
 30             </div>
 31             <div>
 32                 <table border = 0 id = "week" >
 33                     <tr>
 34                         <td>Sun</td>
 35                         <td>Mon</td>
 36                         <td>Tue</td>
 37                         <td>Wed</td>
 38                         <td>Thu</td>
 39                         <td>Fri</td>
 40                         <td>Sat</td>
 41                     </tr>
 42                 </table>
 43             </div>
 44             <div id = "month2">
 45             <table id = "day" border ="1" cellpadding="0" cellspacing="0">
 46                 <tr>
 47                     <td></td>
 48                     <td></td>
 49                     <td></td>
 50                     <td></td>
 51                     <td></td>
 52                     <td></td>
 53                     <td></td>
 54                 </tr>
 55                 <tr>
 56                     <td></td>
 57                     <td></td>
 58                     <td></td>
 59                     <td></td>
 60                     <td></td>
 61                     <td></td>
 62                     <td></td>
 63                 </tr>
 64                 <tr>
 65                     <td></td>
 66                     <td></td>
 67                     <td></td>
 68                     <td></td>
 69                     <td></td>
 70                     <td></td>
 71                     <td></td>
 72                 </tr>
 73                 <tr>
 74                     <td></td>
 75                     <td></td>
 76                     <td></td>
 77                     <td></td>
 78                     <td></td>
 79                     <td></td>
 80                     <td></td>
 81                 </tr>
 82                 <tr>
 83                     <td></td>
 84                     <td></td>
 85                     <td></td>
 86                     <td></td>
 87                     <td></td>
 88                     <td></td>
 89                     <td></td>
 90                 </tr>
 91                 <tr>
 92                     <td></td>
 93                     <td></td>
 94                     <td></td>
 95                     <td></td>
 96                     <td></td>
 97                     <td></td>
 98                     <td></td>
 99                 </tr>
100             </table>
101             </div>
102         </div>
103     </div>
104 
105     <script type="text/javascript" src = "js/date.js"></script>
106 </body>
107 </html>

 

 

CSS代码

 1         body{
 2             background: url(../img/img1.jpg);
 3             Background-size:100%;
 4         }
 5         #main{
 6             margin:30px auto;
 7             height: 600px;
 8             width: 700px;
 9             background: rgba(255,255,255,0.5);
10         }
11         #title{
12             text-align: left;
13             padding-top: 5px;
14             padding-left: 20px;
15         }
16         #btn{
17             background: #036;
18             color: white;
19             border: none;
20             outline: none;
21             height: 30px;
22             width: 70px;
23         }
24         input{
25             height: 25px;
26             width: 180px;
27         }
28         #calendar{
29             width: 350px;
30             height:auto;
31             margin-top: 10px;
32         }
33         #date{
34             font-size:x-large;
35             height: 50px;
36             width: 100%;
37             background: #036;
38             border-radius: 5px;
39             margin: 0 auto;
40             color: white;
41         }
42 
43         #week{
44             height: 50px;
45             width: 100%;
46             background: #ccc;
47             text-align: center;
48             font-weight:600;
49         }
50         #week tr td{
51             width: 50px;
52         }
53         #day{
54             width:100%;
55             background: #ccc;
56             text-align: center;
57         }
58         #day tr td{
59             height: 50px;
60             width: 50px;
61         }
62         .t{
63             background: white;
64         }

 

 

 

这些都做完,一个大概的轮廓就出来了

 

 

 

那么接下来,就是获取输入的年月,并渲染了

 

JS实现

 

思路分析

年月的获得,就是节点取值的问题,为了方便后续进行,我加了简单的正则判断

 

var year_reg = /^\d{1,4}$/;
var month_reg = /^1[0-2]$|[1-9]/;

 

 

然后我需要几个很关键的数据

首先是上个月的天数,因为在大多数情况下,第一行我需要用灰色显示上个月的几天。

同时考虑到如果是一月,那么上一月的年份也会换,所以也加了判断条件。

var lastDate = parseInt(month==1?31:new Date(year,month-1,0).getDate());

 

 

其次是当前月的天数,因为后面要获取到下个月开始的日期

var thisDate =  parseInt(new Date(year,month,0).getDate());

 

 

然后是当前月第一天的星期

var thisDate_one =  parseInt(new Date(year,month-1,1).getDay());

 

由于最后一个参数不是0,所以月份要-1(取值范围的问题)

 

然后是复杂的循环的拼(字符)串,这也是日历的核心

 1         var str = "<table id = 'day' border ='1' cellpadding='0' cellspacing='0'>";
 2         for(let i = 1;i<=6;i++){
 3             str+="<tr>";
 4             for(let j = 1;j<=7;j++){
 5                 if(i==1){
 6                     str+=j<thisDate_one+1?"<td>"+(lastDate-thisDate_one+j)+"</td>":"<td class='t'>"+(j-thisDate_one)+"</td>";
 7                 }else if(i>=5){
 8                     str+=(j-thisDate_one+(i-1)*7)>thisDate?"<td>"+(j-thisDate_one+(i-1)*7)%thisDate+"</td>":"<td class='t'>"+(j-thisDate_one+(i-1)*7)+"</td>";
 9                 }else{
10                     str+="<td class='t'>"+(j-thisDate_one+(i-1)*7)+"</td>";
11                 }
12             }
13             str+="</tr>";
14         }
15         str+="</table>";
16         day.innerHTML = str;
17         return;

 

 

最重要的就是第四行的for循环里面。

会有三种情况,就是首行,中间,尾行(1行或两行)

 

首行,判断i==1

  然后再与第一天的星期相比,小于则执行上个月的循环。

  拿2020年8月举例

  第一天是周六,那么第一天之前,他的<td>里的数据就是上个月的天数  -  这个月的天数   +  j(行号)   

  即    

lastDate-thisDate_one+j

 

代码上加上了括号是因为NaN的问题

 

然后当前月的循环就是   行号-当前月的第一天

j -  thisDate_one

 

 

第二个判断条件是尾行,我们知道从第五行开始,可能就进入了下个月,那么又要重新考虑逻辑

判断是否进入了下个月,需要判断是否大于当前月的天数,这里也使用了一个三目运算

 str+=(j-thisDate_one+(i-1)*7)>thisDate?"<td>"+(j-thisDate_one+(i-1)*7)%thisDate+"</td>":"<td class='t'>"+(j-thisDate_one+(i-1)*7)+"</td>";

 

因为周数的迭代,所以要加上( i - 1 )* 7   同时巧妙的利用取余运算来得出<td>的内容

后面因为小于,按正常计算就可以

 

中间比较简单

str+="<td class='t'>"+(j-thisDate_one+(i-1)*7)+"</td>";

 

 

接下来是完整的JS代码

 1 var year_reg = /^\d{1,4}$/;
 2 var month_reg = /^1[0-2]$|[1-9]/;
 3 
 4 function fun(){
 5     var year = document.getElementById("year").value;
 6     var month = document.getElementById("month").value;
 7     if (year_reg.test(year)&&month_reg.test(month)) {
 8         document.getElementById("date2").innerText = year+"年"+month+"月";
 9         var thisDate =  parseInt(new Date(year,month,0).getDate());
10         var lastDate = parseInt(month==1?31:new Date(year,month-1,0).getDate());
11         var day = document.getElementById("month2");
12         var thisDate_one =  parseInt(new Date(year,month-1,1).getDay());
13         var str = "<table id = 'day' border ='1' cellpadding='0' cellspacing='0'>";
14         for(let i = 1;i<=6;i++){
15             str+="<tr>";
16             for(let j = 1;j<=7;j++){
17                 if(i==1){
18                     str+=j<thisDate_one+1?"<td>"+(lastDate-thisDate_one+j)+"</td>":"<td class='t'>"+(j-thisDate_one)+"</td>";
19                 }else if(i>=5){
20                     str+=(j-thisDate_one+(i-1)*7)>thisDate?"<td>"+(j-thisDate_one+(i-1)*7)%thisDate+"</td>":"<td class='t'>"+(j-thisDate_one+(i-1)*7)+"</td>";
21                 }else{
22                     str+="<td class='t'>"+(j-thisDate_one+(i-1)*7)+"</td>";
23                 }
24             }
25             str+="</tr>";
26         }
27         str+="</table>";
28         day.innerHTML = str;
29         return;
30     }
31     alert("输入不合法");
32     return;
33 }

 

 

 

感谢您的阅读

 

标签:thisDate,日历,JS,nbsp,str,year,var,month,秒表
来源: https://www.cnblogs.com/keason/p/14016761.html