Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4276803
  • 博文数量: 79
  • 博客积分: 3046
  • 博客等级: 中校
  • 技术积分: 723
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-18 21:46
文章分类

全部博文(79)

文章存档

2010年(5)

2009年(2)

2008年(6)

2007年(66)

我的朋友

分类: Java

2007-04-19 11:29:21

我想做的效果如下图,不要太多的功能,反正是自家用,并且写日历这个也有很多大侠早就写出了很多功能的了,所以我只是出于兴趣才写的.
日历的三层结构:
同样地,在编写这个日历时,我使用了三种结构,这是做网页的通用方法。
第一层:结构层,指(X)HTML标签(TAG),这个日历放在那里,用什么TAG进行显示。
第二层:表示层,由CSS负责,显示什么的样式。
第三层:行为层,这里指的就是用JAVASCIPT创建的行为,负责回答“内容应该如何对事情件做出反应“
简言之:
(1)使用(X)HTML去搭建文档的结构
(2)使用CSS设置文档的显现效果
(3)使用DOM脚本实现文档的行为
 
关联:
TAG 及CSS 的ID都是跟脚本的接口进行关联,像使用document.getElementById(id)或getElementTagName(tag),就必须将其统一,方便以后使用

第一层: 使用什么标签显示这个日期,我觉得用TABLE标签控制比较好,并且我把整个日历都嵌入到一个TABLE中,包括最上面的日期显示,及下面的time,XHTML格式如下:


 
 
  
   
   
   
  
 

 
日期
转到上一个月日历内容转子到下一月
时间

这里使用了,,标签,其实可以不加上去的,只要成对的去掉了就可以了,去掉了就是三行三列的格局.加上去仅出于个人编写的习惯。

这基本就是第一层的工作.

第二层:
定义CSS样式,定义样式必须跟ID对应,(不用TAG对应是考虑到网页上还要相同的TAG,到时候在第三层编写代码时就会带来不必要的麻烦。因为使用getElementTagName(tag)返回的相同的TAG的数组,使用上就麻烦了,好了,不附带太多)

日期:id=date
日历内容: id=calendar
时间:id=now_time(出于编写习惯,只有在定义函数名时我才会用第二个单词开始才使用大写第一个字母,像这样的形式:nowTime.变量,数据成员,参数,id值等都使用下划线分隔单词)
转到上一月:id=next_month
转到下一月: id=prev_month

定义id对应样式如下:(内容略)

只要对样式进行了定义,第二层也就算差不多了. 如图:

 

第三层:
编写相应的代码,这一层是重点,所以内容是很多的。

先说说大体的方向,我打算写一个类,这个日历就是该类的一个实例,那么显示日历内容及更新日历内容将会调用这个实例的数据成员(或者说是属性)和成员函数(或者说是方法).反正重点就是"类"这个字.

从基础做起,解决最基本的问题:
1.javascript 中如何获得一个日期值
      js中有"Date()"这个关键字,来创建一个日期对象.简单来说 var now = new Date();  就可以创建一个Date实例 now,当定义没有对Date()附加参数,那么实例包括的年份、月份、日期、时间等都会以当前系统的日期时间作为相应的值.当然也可以指定一个固定的日期,如: var deadline = new Date(2007,6,14); 这样就创建了另一个Date 对象.而这个deadline 实例对应是日期2007年7月14日,这里要注意Date()的第二个参数是月份,值为0~11,对应月份是1~12月,所以实际月份就要相应的加一,详细关于Date说明可以看看这里:http://blog.chinaunix.net/u1/36483/showart_285316.html
其它必须用到日期还有:
 var date = new Date(2007,4,1);//创建一个实例
 var date_month = date.getMonth();//getMonth()返回date实例所指定的月份
 var date_year = date.getFullYear();//getFullYear()返回date实例所指定的年份(四位数形式)
 var date_weekcn = date.getDay();//getDay()返回date实例所指定的日期是星期几,值为0~6,周日为0,周一为1,如此类推
而getDate()则返回实例的日期(月份中的哪一天)

2.闰年的判断,算出那一年是闰年,主要是计算出2月有多少天
先说说闰年的规则:
一:如果年的数目是 4 的倍数,就是闰年。
二:但是,如果年的数目是 100 的倍数,规则一就无效,仍是常年。
三:但是,如果年的数目是 400 的倍数,规则二就无效,仍是闰年。
代码算法:(不对这个算法进行详细论述了,在网上用的普遍都是这个算法,这里,该函数根据参数直接输入某年某月的天数)
function countDays(year,month) //根据参数一跟参数二的年月计算该月有多少天,返回就是该月的天数,一月份对0,二月份对应1,如此类推,是从0开始
{
 var days_in_months = new Array(31,28,31,30,31,30,31,31,30,31,30,31);//定义月份的数组,函数运行可以直接返回一个数值.
 if (1 == month) return ((0 == year % 4) && (0 != (year % 100))) ||(0 == year % 400) ? 29 : 28;
 else return days_in_months[month];
}

3.日历的显示
 我将整个日历封装成一个7行7列的table,,首行是标题,显示周日,周一等...,下面六行就日子显示.
日历要解决问题主要有两个:
1.该月共有多少天,(上面算天数就已经解决他这个问题了,到时调用这个函数就可以了)
2.该月首天是星期几(利用getDay()就可以解决了,上面有提及)

日历类:
我将日历封装成一个类,之后通过这个类的一个实例进行相应的操作.
为了方便向CSS提供接口:把日期(显示年月部分)对应id ,日历内容显示对应的id,以及在日历内容中突出今天而定义一个id ,如下图:

图中提到的ID值,是自行定义的,看一下这个日历的定义就清楚了:
function calendar (date_id,cal_id,today_id)
{...}
该类就是这样定义的了,主要了解的就是其参数,
参数1:用于日期显示的TAG对应的ID值,意思是查找出跟这个ID值相同的TAG,之后将内容显示到这个TAG中
参数2:跟参数1类似,把日历内容显示不到与这个ID值相同的TAG中
参数3:为了在日历内容上,把当天这个日子显示跟其它日子不同,向显示这个日子的TAG加入一个ID,以后用CSS 定义新的样式,值也是用户定义,只要对这个ID 进行CSS定义样式就可以了

方便调用,引入外部文件的方法:

说明:src=""里面就是引入文件的路径.详情:http://blog.chinaunix.net/u1/36483/showart_288795.html
下面是这个类的代码,存于calendar.js中:
/*==========================calendar 类=================================================*/
function calendar(date_id,cal_id,today_id)//参数一是显示年月的标签id,参数二是显示日历内容的标签id,参数三是在日历内容显示当日的样式id
{
/*
*日历类
*主要属性:当前日期年、月、日,动态的年、月、日
*主要方法:转子到上一月,转子到下一月,日历显示,时间显示
*/
this.date_id = date_id;
this.cal_id = cal_id;
this.today_id = today_id;
var today = new Date();
this.year = today.getFullYear();
this.month = today.getMonth();
this.date = today.getDate();
today = null;
this.tmp_year = this.year;
this.tmp_month = this.month;
this.tmp_date= this.date;

this.weekcn = new Array ('日','一','二','三','四','五','六');
this.weekcn_en = new Array ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
this.countDays = function (year,month) //根据参数一跟参数二的年月计算该月有多少天,返回就是该月的天数,一月份对0,二月份对应1,如此类推,是从0开始
    {
        var days_in_months = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
        if (1 == month) return ((0 == year % 4) && (0 != (year % 100))) ||(0 == year % 400) ? 29 : 28;
        else return days_in_months[month];
    }

this.calendar = function()//日历的内容
    {    
        var date = new Date(this.tmp_year,this.tmp_month,1);
        var date_month = date.getMonth();
        var date_year = date.getYear();
        var date_weekcn = date.getDay();//星期
        var month_days = this.countDays(date_year,date_month);
        var tmp = 1 - date_weekcn;
        var date_str="";
        //日历显示
        //排列星期的标题
         date_str+="";
         for (var w=0; w<7; w++)
         {
              date_str = date_str+"";//将weekcn[]修改weekcn_en[]日历标题显示为英文
         }
         for (var i=0; i<6; i++)
        {
              date_str+="";
              for (var k=0; k<7; k++)
            {
                   if ((this.year==this.tmp_year)&&(this.month == this.tmp_month)&&(this.date == tmp))
                    date_str+="";
              }
              date_str+="";
         }
        date_str+="
"+this.weekcn[w]+"
";//判断是否是当前显示的日期是现时的日期,是则用now 的CSS 样式
                   else
                       date_str+="
";
                   if ((tmp>0)&&(tmp<=month_days)) date_str+=tmp;
                   //else date_str+='n/a';//这里是输出非日期内容的表格显示的内容
                   tmp++;
               date_str+="
";
        return date_str;
    }
    
this.yearMonth = function ()//年月的内容
    {
        var str = this.tmp_year+"年"
        if (this.tmp_month <9) {str = str+"0"+(this.tmp_month+1)+"月";}
        else {str = str+(this.tmp_month+1)+"月";}
        return str;
    }

this.calendarShow = function ()//根据id 输出日历内容
    {
        var calendar_show = document.getElementById(this.cal_id);
        calendar_show.innerHTML = this.calendar();
    }
    
this.yearMonthShow = function ()//根据id 输出年月内容
    {
        var date_show = document.getElementById (this.date_id);
        date_show.innerHTML = this.yearMonth();
    }
    
this.nextMonth = function ()//下一月
    {
        if (this.tmp_month>=11) {this.tmp_month = 0;this.tmp_year +=1;}
        else {this.tmp_month += 1;}
        this.calendarShow();
        this.yearMonthShow();
        return false;
    }
    
this.prevMonth = function ()//上一月
    {
        if (this.tmp_month<=0) {this.tmp_month = 11;this.tmp_year -=1;}
        else {this.tmp_month -= 1;}
        this.calendarShow();
        this.yearMonthShow();
        return false;
    }

    
}
/*==========================calendar 类=================================================*/
/* 现时这个类供外部有效使用的方法(成员函数)包括以下,其它的方法(成员函数)对网页上的内容不会作出任何改变:
*    this.yearMonthShow()// 显示年月
*    this.calendarShow() // 显示日历内容
*    this.nextMonth() // 使日历转到下个月
*    this.prevMonth() // 使日历转到上个月
*/

下面是网页上的代码:







calendar






 
 
 
  
  
  
 
 

 
日期
转到上一月日历内容转到下一月
时间



最后就是对id进行CSS样式的定义.
一个日历基本实现,现时遇到的问题是时间的更新出现一点问题,会在以后补上的

20070504 补上时间更新的解决方法:

先将类中的参数加上去:
function calendar(date_id,cal_id,time_id,today_id)//参数一是显示年月的标签id,参数二是显示日历内容的标签id,参数三是显示时间的标签id,参数四是在日历内容显示当日的样式id
{...}
参数三就是在原类上加上去的.然后在类中加入以下代码:
this.date_id = date_id;
this.cal_id = cal_id;
this.time_id = time_id;//这行就是加入的代码,把这个ID存起来,方便调用
this.today_id = today_id;
...
 
接着就是编写这个类中关于时间显示的成员函数了,代码如下:
this.clock = function ()//时钟显示
 {
 var showtime = document.getElementById(this.time_id);
 var now = new Date();
 var hours = now.getHours();
 var minutes = now.getMinutes();
 var seconds = now.getSeconds();
 if (hours<10) hours = "0"+hours;
 if (minutes<10) minutes = "0"+minutes;
 if (seconds<10) seconds = "0"+seconds;
 var showstr = hours+":"+minutes+":"+seconds;
 showtime.innerHTML=showstr;
 var self = this;
 setTimeout(function(){self.clock();},500);
 }
这个成员函数重点就在于红色字的这两行,首先将关键字"this",赋到一个变量去,第二就在是setTimeout()中的第一个参数用function 方法封装起来.
 
最后就是更新类的实例定义,及在的"onload"中多调用一个时钟成员函数






无标题文档
 

onload="cal.calendarShow();cal.yearMonthShow();cal.clock();">

 
 
 
  
  
  
 
 
 

日期
转到上一月日历内容转到下一月
时间


阅读(11021) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:电脑配件功耗

给主人留下些什么吧!~~