Stanford CS142: Web Applications Week3 Project 3: JavaScript and the DOM
DatePicker.js
效果:
/* eslint-disable no-unused-vars */
'use strict';
class DatePicker {
constructor(id, callback) {
this.date = undefined;
this.id = id;
this.callback = callback;
}
render(date) {
this.date = date;
this.update();
}
createTableP() {
const td = document.createElement('p');
td.setAttribute('onmouseover', 'MouseOverCell(event);');
td.setAttribute('onmouseout', 'MouseOutCell(event);');
td.addEventListener('click', (event) => {
const attribute = event.target.getAttribute("class");
if (!attribute) {
this.callback(this.id, {
year: this.date.getFullYear(),
month: this.date.getMonth() + 1,
day: event.target.textContent
});
}
});
return td;
}
update() {
const root = document.getElementById(this.id);
const table = document.createElement('table');
root.appendChild(table);
const headers = ['Sun', 'Mon', 'Tues', 'Wed', 'Thur', 'Fri', 'Sat'];
table.style.border = '1';
/* 添加日历的头部 */
const topRow = document.createElement('tr');
const header = document.createElement('tr');
topRow.setAttribute('class', 'TopRow');
table.appendChild(topRow);
table.appendChild(header);
const top = document.createElement('th');
top.setAttribute('class', 'TopTitle');
top.setAttribute('colspan', '7');
const topTitle = document.createElement('span');
topTitle.setAttribute('class', 'TopTitleText');
topTitle.textContent = `${this.date.getMonth() + 1} ${this.date.getFullYear()}`;
topTitle.setAttribute(onmouseover, 'MouseOverTitle(event);');
topTitle.setAttribute(onmouseout, 'MouseOutTitle(event);');
topRow.appendChild(top);
const lastButton = document.createElement('button');
const nextButton = document.createElement('button');
lastButton.addEventListener("click", () => {
this.date.setMonth(this.date.getMonth() - 1);
this.update();
table.remove();
});
lastButton.textContent = '<';
nextButton.addEventListener('click', () => {
this.date.setMonth(this.date.getMonth() + 1);
this.update();
table.remove();
});
nextButton.textContent = '>';
top.appendChild(lastButton);
top.appendChild(topTitle);
top.appendChild(nextButton);
for (var day of headers) {
const e = document.createElement('th');
e.textContent = day;
header.appendChild(e);
}
/* 添加每个星期的日期 */
const date = new Date(this.date);
date.setDate(1);
const first_row = document.createElement('tr');
let i = 0;
/* 上个月的补全*/
date.setDate(date.getDate() - date.getDay());
for (; date.getMonth() !== this.date.getMonth(); ++i) {
const cell = document.createElement('td');
const p = this.createTableP();
p.setAttribute('class', 'NotThisMonth');
cell.appendChild(p);
p.textContent = date.getDate();
first_row.appendChild(cell);
date.setDate(date.getDate() + 1);
}
/* 下个月的补全*/
let row = first_row;
while (this.date.getMonth() === date.getMonth()) {
for (; i < 7 && this.date.getMonth() === date.getMonth(); i++) {
const cell = document.createElement('td');
const p = this.createTableP();
p.textContent = date.getDate();
cell.appendChild(p);
date.setDate(date.getDate() + 1);
row.appendChild(cell);
}
table.appendChild(row);
if (i >= 7) {
row = document.createElement('tr');
i = 0;
}
}
while (date.getDay() > 0) {
const cell = document.createElement('td');
const p = this.createTableP();
p.setAttribute('class', 'NotThisMonth');
cell.appendChild(p);
row.appendChild(cell);
p.textContent = date.getDate();
date.setDate(date.getDate() + 1);
}
}
}
function MouseOverCell(event) {
event.target.setAttribute("id", "MouseOver");
}
function MouseOutCell(event) {
event.target.removeAttribute("id");
}
function MouseOutTitle(event) {
event.target.removeAttribute("Title");
}
function MouseOverTitle(event) {
event.target.setAttribute("id", "Title");
}
TableTemplate.js
'use strict';
class TableTemplate {
static fillIn(id, dict, columnName) {
const table = document.getElementById(id);
table.style.visibility = "visible";
if (!columnName) {
const fill = new Cs142TemplateProcessor(table.innerHTML);
table.innerHTML = fill.fillIn(dict);
}
else if (columnName === "Part Number") {
let row = table.firstElementChild.firstElementChild;
while (row) {
const c = row.firstElementChild;
const fill = new Cs142TemplateProcessor(c.textContent);
c.textContent = fill.fillIn(dict);
row = row.nextElementSibling;
}
}
else if (columnName === "Length") {
let row = table.firstElementChild.firstElementChild;
while (row) {
const c = row.lastElementChild;
const fill = new Cs142TemplateProcessor(c.textContent);
c.textContent = fill.fillIn(dict);
row = row.nextElementSibling;
}
}
}
}