javascript代码实例教程-javascript动手写日历组件(1)――构建日历逻辑 (by vczero)

发布时间:2019-01-27 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了javascript代码实例教程-javascript动手写日历组件(1)――构建日历逻辑 (by vczero)脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。 一、分析日历的组成部分和交互要素

 

(1)组成部分:选择年月部分、星期显示、包含本月(或者有前月和下一个月部分日子

 

(2)根据选择的年和月份,动态绘制日历面板。

 

(3)一个日历 7(天) * 5(周) = 35格表格。

 

(4)一个月份是统一的一个面板;一个月的头一天一定在日历面板的第一行,根据该天的“星期几”确定位置。

 

(5)第一格子是星期一,最后一个格子是星期日,为5周的日历面板。

 

二、确定逻辑设计

 

 

 

日历上面的日历,8月1号建军节为什么会出现在这一格?因为一个月的天数是小于5周(35天)的,因此,在第一行肯定包含了一个月份的第一天,而这一天的位置是根据该天的星期几来确定的,比如7月的1号是星期二,那么7月1号在第一行的星期二的位置上,然后依次类推,计算前一个月在面板上显示的日期,下一个月在面板上显示的日期。

 

可以将每一个表格看成是一个日期对象,那么下一步的目的就是根据传入不同年份和月份,计算出面板上显示的日期对象数组

 

三、构建日历类

 

(1)首先,构建一个可以传入DOM DIV的日历类。

 

1 VAR Calendar = function(p){

2     this.p = document.getElementById(p);

3 };

5 Calendar.week = ['星期一', '星期二','星期三', '星期四','星期五', '星期六', '星期日'];

6 Calendar.month = ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'];

(2)日历面板逻辑实现。

 

一个日历面板包含3个日期对象数组,第一个是PReMonth,因为,也许该日历面板上会显示前一个月的一些日期;第二个是本月的日期currentMonth;第三个是下一个月的日期数组,nextMonth。定义一个函数monthPanel代表一个日历面板,返回值是三个数组合并的对象。

 

如何计算前一个月会显示多少日期?首先计算选择的月份的第一天在第一行(从0开始计算)占据着第几个位置(4),然后上一个月的总天数(31)减去该位置向上索取,即31-4,31-3,31-2,31-1,31.,那么结果就是31-4,31-3,31-2,31-1,31, 1。

 

如何计算下一个月会显示多少日期?很好办,总共35个格子,那么35 - 当前月份的天数 - 当前月份占据的位置n+1 就是要显示的下一个的日期格子数。

 

综合后的代码如下:

 

复制代码

 1 Calendar.prototyPE.monthPanel = function(date){

 2     //如果传递了Date对象,则按Date对象进行计算月份面板

 3     //否则,按照当前月份计算面板

 4     var date = date || new Date(),

 5         year = date.getFullYear(),

 6         month = date.getMonth(),

 7         day = date.getDate(),

 8         week = date.getDay(),

 9         currentDays = new Date(year, month + 1, 0).getDate(),

10         predays = new Date(year, month, 0).getDate(),

11         FirstDay = new Date(year, month, 1),

12         firstCell = firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1,

13         bottomCell =  35 - currentDays - firstCell;

14     //前一个月该显示多少天

15     var preMonth = [];

16     for(var p = firstCell; p > 0; p--){

17         preMonth.push(new Date(year, month - 1, preDays - p + 1));

18     }

19     //本月

20     var currentMonth = [];

21     for(var c = 0; c < currentDays; c++){

22         currentMonth.push(new Date(year, month, c + 1));

23     }

24     //下一个月

25     var nextMonth = [];

26     for(var n = 0; n < bottomCell; n++){

27         nextMonth.push(new Date(year, month + 1, n + 1));

28     }

29 

30     preMonth = preMonth.concat(currentMonth, nextMonth);

31     return preMonth;

32 };

复制代码

(3)检测代码逻辑是否正确,正好在使用node cmd,所以索性在node下运行了(当如放到Chrome console也可以),不过需要先注释掉this.p = document.getElementById(p);这一行。var c = new Calendar();console.LOG(c.monthPanel(new Date(2014, 6, 1))); 其实不传递参数,就是显示当前月份的日历面板。如下图。

 

 

 

三、构建最基础的UI

 

(1)动态绘制35个表格

 

复制代码

 1     for(var i = 0; i < 35; i++){

 2         var cellDOM = document.createElement('p');

 3         cellDOM.style.width = cell.width + 'px';

 4         cellDOM.style.height = cell.height + 'px';

 5         cellDOM.style.display = 'inline-block';

 6         cellDOM.style.float = 'left';

 7         cellDOM.style.border = '1px solid blue';

 8         cellDOM.style.cursor = 'pointer';           this.p.appendChild(cellDOM);

11     }

复制代码

 

 

(2)显示日期和月份的头部

 

复制代码

 1 Calendar.prototype.showUI = function(date){

 2     var width = this.p.style.width || 800,

 3         height = this.p.style.height || (600 - 30),

 4         cell = {width: (parseInt(width) - 20)/7, height: (parseInt(height) -30 - 20)/5},

 5         monthArr = this.monthPanel(date);

 6 

 7     this.addHeader(date);

 8     for(var i = 0; i < 35; i++){

 9         var cellDOM = document.createElement('p');

10         cellDOM.style.width = cell.width + 'px';

11         cellDOM.style.height = cell.height + 'px';

12         cellDOM.style.display = 'inline-block';

13         cellDOM.style.float = 'left';

14         cellDOM.style.border = '1px solid blue';

15         cellDOM.style.cursor = 'pointer';

16         cellDOM.innerHTML = monthArr[i].getDate();

17         this.p.appendChild(cellDOM);

18     }

19     

20 };

21 

22 Calendar.prototype.addHeader = function(date){

23     var header = document.createElement('p');

24     header.style.height = '20px';

25     header.style.width = this.p.style.width || '800px';

26     header.style.textAlign = 'center';

27     header.style.fontWeight = 'bold';

28     header.innerHTML = date.getFullYear() + '年' + (date.getMonth() + 1) + '月';

29     console.log(header);

30     this.p.appendChild(header);

31 }

复制代码

(3)编写HTML和整个逻辑代码

 

HTML:

 

复制代码

<!doctype html>

<html>

    <head>

        <;meta charset="utf-8" />

        <script type="text/javascript" src="calendar.js"></script>

        <script type="text/javascript">

            function showCalendar(){

                var c = new Calendar('calendar');

                c.showUI(new Date());

            }

        </script>

    </head>

    <body onload="showCalendar()">

        <p id="calendar" style="width:600px; height:400px;border:1px solid red;"></p>

    </body>

</html>

复制代码

javascript:

 

复制代码

 1 var Calendar = function(p){

 2     this.p = document.getElementById(p);

 3 };

 4 

 5 Calendar.week = ['星期一', '星期二','星期三', '星期四','星期五', '星期六', '星期日'];

 6 Calendar.month = ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'];

 7 

 8 Calendar.prototype.showUI = function(date){

 9     var width = this.p.style.width || 800,

10         height = this.p.style.height || (600 - 30),

11         cell = {width: (parseInt(width) - 20)/7, height: (parseInt(height) -30 - 20)/5},

12         monthArr = this.monthPanel(date);

13 

14     this.addHeader(date);

15     for(var i = 0; i < 35; i++){

16         var cellDOM = document.createElement('p');

17         cellDOM.style.width = cell.width + 'px';

18         cellDOM.style.height = cell.height + 'px';

19         cellDOM.style.display = 'inline-block';

20         cellDOM.style.float = 'left';

21         cellDOM.style.border = '1px solid blue';

22         cellDOM.style.cursor = 'pointer';

23         cellDOM.innerHTML = monthArr[i].getDate();

24         this.p.appendChild(cellDOM);

25     }

26     

27 };

28 

29 Calendar.prototype.addHeader = function(date){

30     var header = document.createElement('p');

31     header.style.height = '20px';

32     header.style.width = this.p.style.width || '800px';

33     header.style.textAlign = 'center';

34     header.style.fontWeight = 'bold';

35     header.innerHTML = date.getFullYear() + '年' + (date.getMonth() + 1) + '月';

36     console.log(header);

37     this.p.appendChild(header);

38 }

39 

40 Calendar.prototype.monthPanel = function(date){

41     //如果传递了Date对象,则按Date对象进行计算月份面板

42     //否则,按照当前月份计算面板

43     var date = date || new Date(),

44         year = date.getFullYear(),

45         month = date.getMonth(),

46         day = date.getDate(),

47         week = date.getDay(),

48         currentDays = new Date(year, month + 1, 0).getDate(),

49         preDays = new Date(year, month, 0).getDate(),

50         firstDay = new Date(year, month, 1),

51         firstCell = firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1,

52         bottomCell =  35 - currentDays - firstCell;

53     //前一个月该显示多少天

54     var preMonth = [];

55     for(var p = firstCell; p > 0; p--){

56         preMonth.push(new Date(year, month - 1, preDays - p + 1));

57     }

58     //本月

59     var currentMonth = [];

60     for(var c = 0; c < currentDays; c++){

61         currentMonth.push(new Date(year, month, c + 1));

62     }

63     //下一个月

64     var nextMonth = [];

65     for(var n = 0; n < bottomCell; n++){

66         nextMonth.push(new Date(year, month + 1, n + 1));

67     }

68 

69     preMonth = preMonth.concat(currentMonth, nextMonth);

70     return preMonth;

71 };

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! js脚本,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的javascript代码实例教程-javascript动手写日历组件(1)――构建日历逻辑 (by vczero)全部内容,希望文章能够帮你解决javascript代码实例教程-javascript动手写日历组件(1)――构建日历逻辑 (by vczero)所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。