基本思路
- 创建6*7表格
创建表格
- table 的构成 <table>,<tr>, <td>
- javasript modify methods:
document.createElement("table")
同理tr,td。table .insertRow()
,table.insertCell()
,table.remove()
,td.innerHTML = "foo"
- javascript traverse methods ````,
document.getElementByTagName(table)
,同理tr,td。document.getElementByTagName(td)
returns an array of <tr><\tr> elements。或者使用document.getElementByID(id)
- table.rows对象:
rows.item
,rows.length
菜鸟教程
构建简单表格
// 1. create a table and set attributes
var _table = document.createElement("table");
_table.setAttribute("border","1");
_table.setAttribute("borderColor","black");
_table.setAttribute("width","200");
// 1.1 set row
for(var i=0;i<6;i++){
var _tr=_table.insertRow(i);
// 1.2 set col
for(var j=0;j<7;j++){
var _td=_tr.insertCell(j);
}
}
// 1.3 get container and append the table
var container = document.getElementById("datepicker1");
container.appendChild(_table);
完成createCalender()
以上的创建表格只是最简单的空表格, 这里我们的表格是一个可以互动的calendar
其中的for loop遍历了这个表格并且调用addDay()
, addHead()
, addWeek()
来个每个空赋值
createCalendar (date) {
// 1. create a table and set attributes
var table = document.createElement("table");
table.setAttribute("id", "table");
// 1.1 set content
// I must add 'this' here, I don't know why
this.addHead(table, date);
let flag = {value : 0}; // check if there is row7;
for(var i=1;i<8;i++){
// row
var _tr = table.insertRow(i);
for(var j=0;j<7;j++){
// column
var _td=_tr.insertCell(j);
if(i === 1){
this.addWeek(j, _td);
} else {
this.addDay(i, j, date, _td, flag);
}
}
}
// if there isn't row7, delete it
if(flag.value !== 1) {
table.deleteRow(7);
if(table.rows[6].cells[0].innerHTML === "1"){
table.deleteRow(6);
}
}
// 1.2 get container and append the table
// we do it in render()
// var container = document.getElementById("datepicker1");
// container.appendChild(table);
return table;
}
完成addHead(), addDay(), addWeek()
addHead()
就是加入month, year和左右箭头,点击左右箭头有功能
addHead (table, date) {
// month and year
var head = table.createTHead();
var headRow = head.insertRow(0);
var leftArrowCell = headRow.insertCell(0);
leftArrowCell.innerHTML = "<";
leftArrowCell.setAttribute("id", "LeftArrow");
var monthCell = headRow.insertCell(1);
monthCell.innerHTML = this.months[date.getMonth()] + " " + date.getFullYear();
monthCell.colSpan = "5";
var rightArrowCell = headRow.insertCell(2);
rightArrowCell.innerHTML = ">";
rightArrowCell.setAttribute("id", "RightArrow");
// event handler.
leftArrowCell.addEventListener("click", () => {
table.remove();
date.setMonth(date.getMonth() - 1);
console.log(date);
this.render(date);
});
rightArrowCell.addEventListener("click", () => {
table.remove();
date.setMonth(date.getMonth() + 1);
console.log(date);
this.render(date);
});
}
addWeek()
addWeek(j, _td) {
// var _tn = document.createTextNode(weekName[j]);
var _tn = this.weekName[j];
_td.innerHTML = _tn;
}
addDay()
屁事比较多,我需要判断这个月的第一天是哪一天,应该从哪个空开始填。我在填的时候分为三个部分,这个月,下个月和上个月
addDay(i, j, date, _td, flag) {
// row = i; col = j
// _td is this cell
var my_year = date.getFullYear();
var my_month = date.getMonth();
var my_day = date.getDate();
// calculate the start day of a month
function dayStart(month, year) {
var tmpDate = new Date(year, month, 1);
return (tmpDate.getDay());
}
// calculate leap year
var self = this; // cannot call this.month_normal in the daysMonth function
function daysMonth(month, year) {
var leap = (year%4===0 && year%100!==0 || year%400 ===0);
if (leap) {
return (self.month_olympic[month]);
} else {
return (self.month_normal[month]);
}
}
var firstDay = dayStart(my_month, my_year);
var totalDay = daysMonth(my_month, my_year);
var lastDate = new Date(date);
lastDate.setMonth(lastDate.getMonth()-1);
var nextDate = new Date(date);
nextDate.setMonth(nextDate.getMonth()+1);
var _tn;
if(i === 2 && j < firstDay) {
// last month
_tn = daysMonth(lastDate.getMonth(), lastDate.getFullYear()) + (j-firstDay+1);
_td.innerHTML = _tn;
_td.setAttribute("id" , "other");
// this.hintClick(_td, lastDate, _tn);
} else if((i-2)*7+j-firstDay+1 <= totalDay){
// date: (i-2)*7+j-firstDay+1
_tn = (i-2)*7+j-firstDay+1;
_td.setAttribute("id" , "this");
_td.innerHTML = _tn;
this.hintClick(_td, date,_tn);
if(i === 7) {
flag.value = 1;
}
} else {
// next month
if(flag.value === 1 || i < 7) {
_td.setAttribute("id" , "other");
_tn = (i-2)*7+j-firstDay+1-totalDay;
_td.innerHTML = _tn;
// this.hintClick(_td, nextDate, _tn);
}
}
}
// click这个月的日子控制台会返回其信息
hintClick(_td, date,_tn) {
let property = {
month: this.months[date.getMonth()],
day: _tn,
year: date.getFullYear()
};
_td.addEventListener("click", () => {
this.callback(this.id, property);
});
}
类的构造
以上全部作为方法放到类里面,类包括一些需要调用的常量,并且画出表格(之前知识定义了,但是没有添加到HTML文件里面)
class DatePicker {
constructor(id, callback) {
this.id = id;
this.callback = callback;
this.weekName = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
this.months = ["January","February","March","April","May","June",
"July","August","September","October","November","December"];
this.month_normal = [31,28,31,30,31,30,31,31,30,31,30,31];
this.month_olympic = [31,29,31,30,31,30,31,31,30,31,30,31];
}
render(date) {
// argument consisting of a Date object
// selects a particular month (the object can refer to any time within the month).
// When render is invoked it replaces the contents of the
// date picker's div with HTML that displays a small one-month calendar
var parent = document.getElementById(this.id);
parent.appendChild(this.createCalendar(date));
}
}
HTML文件
创建一个对象
datePicker1 = new DatePicker("datepicker1", function (id, fixedDate) {
console.log("DatePicker with id", id,
"selected date:", fixedDate.month + "/" + fixedDate.day + "/" + fixedDate.year);
});