• 原生js打造日程表-支持鼠标滚轮滚动选择月份-可以移植到任何框架中


     

    1. <html>
    2. <head>
    3. <style>
    4. * {
    5. box-sizing: border-box;
    6. }
    7. .calendar {
    8. width: 100%;
    9. border: 1px solid #e7e7e8;
    10. user-select: none;
    11. }
    12. .calendar .calendar_title {
    13. padding: .5em 0 .5em 0;
    14. text-align: center;
    15. border-bottom: 1px solid #e7e7e8
    16. }
    17. .calendar .calendar_week {
    18. padding: .5em 0 .5em 0;
    19. }
    20. .calendar .calendar_week span {
    21. width: 14.2857%;
    22. text-align: center;
    23. display: inline-block;
    24. }
    25. .calendar .calendar_dateCon .noEmpty {
    26. padding: .5em;
    27. width: 14.2857%;
    28. text-align: left;
    29. display: inline-block;
    30. min-height: 120px;
    31. float: left;
    32. }
    33. .calendar .calendar_dateCon {
    34. border-bottom: 1px solid #e7e7e8;
    35. }
    36. .calendar .calendar_dateCon::after {
    37. content: '';
    38. display: block;
    39. clear: both;
    40. }
    41. .calendar .noEmpty {
    42. border: 1px solid #e7e7e8;
    43. border-right: 0px;
    44. border-bottom: 0px;
    45. }
    46. .calendar .noEmpty:nth-child(7n) {
    47. border-right: 1px solid #e7e7e8;
    48. }
    49. .dayNumText {
    50. font-weight: 800;
    51. font-size: 14px
    52. }
    53. .activeDay .dayNumText {
    54. background: #267ef0;
    55. color: white!important;
    56. border-radius: 100%;
    57. width: 30px;
    58. height: 30px;
    59. text-align: center;
    60. line-height: 30px;
    61. font-size: 12px;
    62. }
    63. .icon {
    64. width: 16px;
    65. height: 16px;
    66. vertical-align: -0.2em;
    67. cursor: pointer;
    68. }
    69. .icon:hover {
    70. transform: scale(1.2);
    71. }
    72. .prevMonth .dayNumText,
    73. .nextMonth .dayNumText {
    74. color: gray
    75. }
    76. .firstLine {
    77. display: flex;
    78. justify-content: space-between;
    79. }
    80. .blueDot {
    81. background: #2d8eff;
    82. width: 5px;
    83. height: 5px;
    84. display: inline-block;
    85. border-radius: 100%;
    86. vertical-align: 0.1em;
    87. }
    88. .taskLine,
    89. .taskLineMore {
    90. font-size: 12px;
    91. margin-top: 5px;
    92. }
    93. .taskLineMore {
    94. color: #6d7176
    95. }
    96. .taskLine>span {
    97. margin-right: 5px;
    98. }
    99. .nowMonth {
    100. /* background: repeating-linear-gradient(45deg, rgb(212, 209, 209) 7%, #fff 10%); */
    101. }
    102. </style>
    103. </head>
    104. <body>
    105. <div id="rili"></div>
    106. <script type="text/javascript">
    107. // 判断是否是闰年
    108. function isLeapYear(year) {
    109. return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);
    110. }
    111. // 关键!关键!关键!
    112. // 获取某年某月的第一天是周几
    113. function getMonthFirstDayWeek(year, month) {
    114. var month = +month - 1;
    115. var date = new Date();
    116. date.setFullYear(year);
    117. date.setMonth(month);
    118. date.setDate(1);
    119. return date.getDay();
    120. }
    121. // 获取某年某月的天数
    122. function getDay(year, month) {
    123. var month = +month;
    124. // 天的数组
    125. var day31 = [];
    126. var day30 = [];
    127. var day29 = [];
    128. var day28 = [];
    129. for (var i = 1; i <= 31; i++) {
    130. day31.push(i);
    131. if (i <= 30) {
    132. day30.push(i);
    133. }
    134. if (i <= 29) {
    135. day29.push(i);
    136. }
    137. if (i <= 28) {
    138. day28.push(i);
    139. }
    140. }
    141. if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
    142. return day31;
    143. }
    144. if (month == 4 || month == 6 || month == 9 || month == 11) {
    145. return day30;
    146. }
    147. // 当月份等于2时,如果是闰年就返回29天,如果是平年就返回28天
    148. if (month == 2) {
    149. if (isLeapYear(year)) {
    150. return day29;
    151. } else {
    152. return day28;
    153. }
    154. }
    155. }
    156. // 年
    157. var year = new Date().getFullYear();
    158. // 月
    159. var month = new Date().getMonth() + 1;
    160. var selectNowDay = "[year='" + new Date().getFullYear() + "']" + "[month='" + (new Date().getMonth() + 1) + "']" + "[value='" + (new Date().getDate()) + "']"
    161. function prevMonthClick() {
    162. if (month == 1) {
    163. var prevMonth = 12;
    164. var prevYear = +year - 1;
    165. } else {
    166. var prevMonth = +month - 1;
    167. var prevYear = +year;
    168. }
    169. year = prevYear;
    170. month = prevMonth;
    171. document.getElementById("rili").innerHTML = createRi(prevYear, prevMonth);
    172. if (document.querySelector(selectNowDay)) {
    173. document.querySelector(selectNowDay).classList.add("activeDay")
    174. document.querySelector(selectNowDay).querySelector(".taskCon").innerHTML = `
    175. <div class="taskLine"><span class='blueDot'></span><span>14:00</span><span>无主题</span></div>
    176. <div class="taskLine"><span class='blueDot'></span><span>14:00</span><span>无主题</span></div>
    177. <div class="taskLineMore">还有两个日程</div>
    178. `
    179. }
    180. }
    181. function nextMonthClick() {
    182. // 下一个月份
    183. if (month == 12) {
    184. var nextMonth = 1;
    185. var nextYear = +year + 1;
    186. } else {
    187. var nextMonth = +month + 1;
    188. var nextYear = year;
    189. }
    190. year = nextYear;
    191. month = nextMonth;
    192. document.getElementById("rili").innerHTML = createRi(nextYear, nextMonth);
    193. if (document.querySelector(selectNowDay)) {
    194. document.querySelector(selectNowDay).classList.add("activeDay")
    195. document.querySelector(selectNowDay).querySelector(".taskCon").innerHTML = `
    196. <div class="taskLine"><span class='blueDot'></span><span>14:00</span><span>无主题</span></div>
    197. <div class="taskLine"><span class='blueDot'></span><span>14:00</span><span>无主题</span></div>
    198. <div class="taskLineMore">还有两个日程</div>
    199. `
    200. }
    201. }
    202. document.onmousewheel = function(event) {
    203. var target = event.target;
    204. var con = document.querySelector(".calendar_dateCon")
    205. if (!con.contains(target)) {
    206. return
    207. }
    208. if (event.deltaY < 0) {
    209. prevMonthClick()
    210. }
    211. if (event.deltaY > 0) {
    212. nextMonthClick()
    213. }
    214. }
    215. document.getElementById("rili").innerHTML = createRi(year, month);
    216. document.querySelector(selectNowDay).classList.add("activeDay");
    217. document.querySelector(selectNowDay).querySelector(".taskCon").innerHTML = `
    218. <div class="taskLine"><span class='blueDot'></span><span>14:00</span><span>无主题</span></div>
    219. <div class="taskLine"><span class='blueDot'></span><span>14:00</span><span>无主题</span></div>
    220. <div class="taskLineMore">还有两个日程</div>
    221. `
    222. function createRi(year, month) {
    223. // 日历头部
    224. var str = '<div class="calendar" value="{{month}}">' +
    225. `<div class="calendar_title">
    226. <svg title="上一月" onclick="prevMonthClick()" t="1656645725615" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2384" width="200" height="200"><path d="M910.222222 796.444444c-17.066667 0-34.133333-5.688889-45.511111-17.066666L551.822222 409.6c-11.377778-5.688889-17.066667-11.377778-34.133333-11.377778-5.688889 0-22.755556 5.688889-28.444445 11.377778l-329.955555 364.088889c-22.755556 22.755556-56.888889 22.755556-79.644445 5.688889-22.755556-22.755556-22.755556-56.888889-5.688888-79.644445l329.955555-364.088889c28.444444-34.133333 73.955556-51.2 119.466667-51.2s85.333333 22.755556 119.466666 56.888889l312.888889 364.088889c22.755556 22.755556 17.066667 56.888889-5.688889 79.644445-11.377778 5.688889-28.444444 11.377778-39.822222 11.377777z" p-id="2385"></path></svg>
    227. <svg title="下一月" onclick="nextMonthClick()" t="1656645659090" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2229" width="200" height="200"><path d="M517.688889 796.444444c-45.511111 0-85.333333-17.066667-119.466667-51.2L73.955556 381.155556c-22.755556-22.755556-17.066667-56.888889 5.688888-79.644445 22.755556-22.755556 56.888889-17.066667 79.644445 5.688889l329.955555 364.088889c5.688889 5.688889 17.066667 11.377778 28.444445 11.377778s22.755556-5.688889 34.133333-17.066667l312.888889-364.088889c22.755556-22.755556 56.888889-28.444444 79.644445-5.688889 22.755556 22.755556 28.444444 56.888889 5.688888 79.644445L637.155556 739.555556c-28.444444 39.822222-68.266667 56.888889-119.466667 56.888888 5.688889 0 0 0 0 0z" p-id="2230"></path></svg>
    228. {{year}}年{{month}}月</div>` +
    229. '<div class="calendar_week">' +
    230. '<span>周日</span><span>周一</span><span>周二</span><span>周三</span><span>周四</span><span>周五</span><span>周六</span>' +
    231. '</div>' +
    232. '<div class="calendar_dateCon">{{days}}</div>' +
    233. '</div>';
    234. // 替换月份
    235. var str = str.replaceAll("{{year}}", year).replaceAll("{{month}}", month);
    236. // 获取某年某月的第一天是周几,周一就代表在天数前面增加一个空格,周二就代表在天数前面增加二个空格
    237. // 周天就代表在天数前面增加零个空格
    238. // 上一个月份
    239. if (month == 1) {
    240. var prevMonth = 12;
    241. var prevYear = +year - 1;
    242. } else {
    243. var prevMonth = +month - 1;
    244. var prevYear = +year;
    245. }
    246. var emptySpanPrev = getMonthFirstDayWeek(prevYear, prevMonth);
    247. var daysPrev = getDay(prevYear, prevMonth);
    248. // 当前月份
    249. var emptySpan = getMonthFirstDayWeek(year, month);
    250. var days = getDay(year, month);
    251. var emptyHeadArr = [];
    252. for (var i = 0; i < emptySpan; i++) {
    253. emptyHeadArr.push(daysPrev[daysPrev.length - emptySpan + i])
    254. }
    255. // 下一个月份
    256. if (month == 12) {
    257. var nextMonth = 1;
    258. var nextYear = +year + 1;
    259. } else {
    260. var nextMonth = +month + 1;
    261. var nextYear = year;
    262. }
    263. var emptySpanNext = getMonthFirstDayWeek(nextYear, nextMonth);
    264. var daysNext = getDay(nextYear, nextMonth);
    265. var emptyEndArr = [];
    266. if (emptySpanNext != 0) {
    267. for (var i = 0; i < (7 - emptySpanNext); i++) {
    268. emptyEndArr.push(daysNext[i])
    269. }
    270. }
    271. // 日历格子
    272. var spanStr = "";
    273. // 天数格子
    274. for (var n = 0; n < emptyHeadArr.length; n++) {
    275. spanStr += "<span class='noEmpty prevMonth' year='" + prevYear + "' month='" + prevMonth + "' value='" + emptyHeadArr[n] + "'><div class='firstLine'><span class='dayNumText'>" + emptyHeadArr[n] + "</span><span></span><span></span></div><div class='taskCon'></div></span>";
    276. }
    277. for (var n = 0; n < days.length; n++) {
    278. if (n == 0) {
    279. spanStr += "<span class='noEmpty nowMonth' year='" + year + "' month='" + (+month) + "' value='" + days[n] + "'><div class='firstLine'><span class='dayNumText'>" + (+month) + "月</span><span></span><span></span></div><div class='taskCon'></div></span>";
    280. } else {
    281. spanStr += "<span class='noEmpty nowMonth' year='" + year + "' month='" + (+month) + "' value='" + days[n] + "'><div class='firstLine'><span class='dayNumText'>" + days[n] + "</span><span></span><span></span></div><div class='taskCon'></div></span>";
    282. }
    283. }
    284. for (var n = 0; n < emptyEndArr.length; n++) {
    285. if (n == 0) {
    286. spanStr += "<span class='noEmpty nextMonth' year='" + nextYear + "' month='" + nextMonth + "' value='" + emptyEndArr[n] + "'><div class='firstLine'><span class='dayNumText'>" + nextMonth + "月</span><span></span><span></span></div><div class='taskCon'></div></span>";
    287. } else {
    288. spanStr += "<span class='noEmpty nextMonth' year='" + nextYear + "' month='" + nextMonth + "' value='" + emptyEndArr[n] + "'><div class='firstLine'><span class='dayNumText'>" + emptyEndArr[n] + "</span><span></span><span></span></div><div class='taskCon'></div></span>";
    289. }
    290. }
    291. // 替换天数格子容器
    292. var str = str.replace("{{days}}", spanStr);
    293. // 返回总的字符串
    294. return str;
    295. }
    296. </script>
    297. </body>
    298. </html>

  • 相关阅读:
    如何理解Python中一切皆对象?
    exe4j使用笔记(jar包转exe工具)
    4-8网络层-网络层设备
    C# 一周入门高级编程之《C#-接口》Day Two
    【笔记】大话设计模式16
    计算机网络 第二节
    YOLOv5算法改进(15)— 如何去更换Neck网络(包括代码+添加步骤+网络结构图)
    微信小程序使用Animate.css动画库
    第四节 基本运算符和变量,数组切片
    LeetCode841. Keys and Rooms
  • 原文地址:https://blog.csdn.net/liuhao9999/article/details/125558943