下面是关于“CSS 制作有弹性的日历表”的完整攻略:
1. 分析需求
首先,我们要明确自己要制作的日历表应该具备哪些功能和特性,比如:
- 支持显示任意年月的日历
- 以表格形式呈现,包括日历视图和周视图两种模式
- 对于当前月份的日期,应该以不同颜色或样式标识出来
- 可以通过点击日历中的日期实现对应日期的选择和显示
当我们明确了需求之后,就可以开始着手制作了。
2. 准备工作
在开始之前,我们需要准备好以下内容:
- 一个 HTML 文件,用于搭建页面结构和组件
- 一个 CSS 文件,用于设置样式和布局
- 一个 JavaScript 文件,用于实现交互和选择逻辑
3. 搭建页面结构
首先,我们需要在 HTML 文件中搭建好页面结构,包括日历的容器和包含日期的表格。具体结构可以参考代码示例:
<div class="calendar-container">
<div class="calendar-header">
<span class="prev-month"><</span>
<span class="current-month"></span>
<span class="next-month">></span>
</div>
<table class="calendar-table">
<thead>
<tr>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
<th>Sat</th>
<th>Sun</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
在这个页面结构中,我们定义了一个名为“calendar-container”的容器元素,用于包裹整个日历表格和其它组件。日历表格本身是一个 <table>
元素,其中包含一个 <thead>
元素和一个空的 <tbody>
元素。<thead>
用于放置表头信息,而<tbody>
通过 JavaScript 脚本来动态生成日期的行和列。
4. 设置样式和布局
接下来,我们需要通过 CSS 文件来设置日历表的样式和布局。具体可以参考以下代码示例:
.calendar-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 300px;
border: 1px solid #ccc;
background-color: #fff;
font-family: Arial, sans-serif;
}
.calendar-header {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 10px;
font-size: 16px;
font-weight: bold;
}
.current-month {
flex: 1;
text-align: center;
}
.calendar-table {
border-collapse: collapse;
margin-top: 10px;
width: 100%;
}
.calendar-table th {
padding: 10px;
text-align: center;
}
.calendar-table td {
padding: 5px;
text-align: center;
vertical-align: middle;
}
.calendar-table td.current-month {
background-color: #eee;
}
.calendar-table td.clicked {
background-color: #ccc;
}
在这个样式文件中,我们设置了日历表格的容器和其它组件的样式,以及日期表格的边框和字体等样式。特别地,我们为当前月份的日期单独设置了背景颜色,以及对于已经被点击过的日期也设置了一个灰色背景。
5. 实现交互和选择
最后,我们需要通过 JavaScript 文件来实现日历表格的交互和日期选择功能。具体可参考以下代码示例:
let currentMonthIndex = new Date().getMonth();
let currentYear = new Date().getFullYear();
function renderCalendar(month, year) {
let startDate = new Date(year, month, 1);
let endDate = new Date(year, month + 1, 0);
let daysInMonth = endDate.getDate();
let tbody = document.querySelector('.calendar-table tbody');
tbody.innerHTML = '';
for (let i = 0; i < 6; i++) {
let tr = document.createElement('tr');
for (let j = 0; j < 7; j++) {
let td = document.createElement('td');
let day = i * 7 + j + 1 - startDate.getDay();
if (day > 0 && day <= daysInMonth) {
td.textContent = day;
td.classList.add('current-month');
if (j == 0 || j == 6) {
td.classList.add('weekend');
}
tr.appendChild(td);
} else {
tr.appendChild(document.createElement('td'));
}
}
tbody.appendChild(tr);
}
let currentDateCells = document.querySelectorAll(`.calendar-table td.current-month`);
currentDateCells.forEach((cell) => {
cell.addEventListener('click', (event) => {
currentDateCells.forEach((c) => {
c.classList.remove('clicked');
});
event.target.classList.add('clicked');
});
});
let currentMonth = document.querySelector('.current-month');
currentMonth.textContent = `${year} - ${startDate.toLocaleString('default', { month: 'long' })}`;
}
renderCalendar(currentMonthIndex, currentYear);
let prevMonth = document.querySelector('.prev-month');
prevMonth.addEventListener('click', () => {
currentMonthIndex -= 1;
if (currentMonthIndex < 0) {
currentMonthIndex = 11;
currentYear -= 1;
}
renderCalendar(currentMonthIndex, currentYear);
});
let nextMonth = document.querySelector('.next-month');
nextMonth.addEventListener('click', () => {
currentMonthIndex += 1;
if (currentMonthIndex > 11) {
currentMonthIndex = 0;
currentYear += 1;
}
renderCalendar(currentMonthIndex, currentYear);
});
在这个 JavaScript 脚本中,我们定义了一个名为“renderCalendar”的函数,用于动态生成日期表格并添加选择逻辑。同时,我们也定义了一些事件监听器,用于实现通过左右箭头来切换不同月份的日历。具体实现细节可以详见代码注释。
6. 示例说明
为了更好地理解和实践上述攻略,下面我将为您演示两个具体的实例。
示例1:日历表的基本显示和交互
在这个示例中,我们先建立好一个空的 HTML 文件和 CSS、JS 文件,并按照上述攻略进行搭建和编写。同时,我们为网页添加一个标题,用于说明页面的用途。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>弹性日历表 DEMO1</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="calendar-container">
<div class="calendar-header">
<span class="prev-month"><</span>
<span class="current-month"></span>
<span class="next-month">></span>
</div>
<table class="calendar-table">
<thead>
<tr>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
<th>Sat</th>
<th>Sun</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<script src="script.js"></script>
</body>
</html>
.calendar-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 300px;
border: 1px solid #ccc;
background-color: #fff;
font-family: Arial, sans-serif;
}
.calendar-header {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 10px;
font-size: 16px;
font-weight: bold;
}
.current-month {
flex: 1;
text-align: center;
}
.calendar-table {
border-collapse: collapse;
margin-top: 10px;
width: 100%;
}
.calendar-table th {
padding: 10px;
text-align: center;
}
.calendar-table td {
padding: 5px;
text-align: center;
vertical-align: middle;
}
.calendar-table td.current-month {
background-color: #eee;
}
.calendar-table td.clicked {
background-color: #ccc;
}
let currentMonthIndex = new Date().getMonth();
let currentYear = new Date().getFullYear();
function renderCalendar(month, year) {
let startDate = new Date(year, month, 1);
let endDate = new Date(year, month + 1, 0);
let daysInMonth = endDate.getDate();
let tbody = document.querySelector('.calendar-table tbody');
tbody.innerHTML = '';
for (let i = 0; i < 6; i++) {
let tr = document.createElement('tr');
for (let j = 0; j < 7; j++) {
let td = document.createElement('td');
let day = i * 7 + j + 1 - startDate.getDay();
if (day > 0 && day <= daysInMonth) {
td.textContent = day;
td.classList.add('current-month');
if (j == 0 || j == 6) {
td.classList.add('weekend');
}
tr.appendChild(td);
} else {
tr.appendChild(document.createElement('td'));
}
}
tbody.appendChild(tr);
}
let currentDateCells = document.querySelectorAll(`.calendar-table td.current-month`);
currentDateCells.forEach((cell) => {
cell.addEventListener('click', (event) => {
currentDateCells.forEach((c) => {
c.classList.remove('clicked');
});
event.target.classList.add('clicked');
});
});
let currentMonth = document.querySelector('.current-month');
currentMonth.textContent = `${year} - ${startDate.toLocaleString('default', { month: 'long' })}`;
}
renderCalendar(currentMonthIndex, currentYear);
let prevMonth = document.querySelector('.prev-month');
prevMonth.addEventListener('click', () => {
currentMonthIndex -= 1;
if (currentMonthIndex < 0) {
currentMonthIndex = 11;
currentYear -= 1;
}
renderCalendar(currentMonthIndex, currentYear);
});
let nextMonth = document.querySelector('.next-month');
nextMonth.addEventListener('click', () => {
currentMonthIndex += 1;
if (currentMonthIndex > 11) {
currentMonthIndex = 0;
currentYear += 1;
}
renderCalendar(currentMonthIndex, currentYear);
});
在浏览器中打开此 HTML 文件,即可看到呈现日历的页面。同时还可以通过左右箭头切换不同月份的日历,并且点击任意日期单元格后,该单元格会以灰色背景标识为已选择状态。
示例2:添加周视图模式
在这个示例中,我们在上一个示例的基础上,增加了一个名为“week-view”的按钮,并为其添加了一个“点击切换至周视图”的监听事件。同时,我们还要修改一些 CSS 样式,以便能够支持周视图模式。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>弹性日历表 DEMO2</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="calendar-container">
<div class="calendar-header">
<span class="prev-month"><</span>
<span class="current-month"></span>
<span class="next-month">></span>
<button class="week-view">周视图</button>
</div>
<table class="calendar-table">
<thead>
<tr>
<th>Mon</th>
<th>Tue</th>
<th>Wed</th>
<th>Thu</th>
<th>Fri</th>
<th>Sat</th>
<th>Sun</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<script src="script.js"></script>
</body>
</html>
.calendar-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 300px;
border: 1px solid #ccc;
background-color: #fff;
font-family: Arial, sans-serif;
}
.calendar-header {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 10px;
font-size: 16px;
font-weight: bold;
}
.current-month {
flex: 1;
text-align: center;
}
.calendar-table,
.calendar-table-week {
border-collapse: collapse;
margin-top: 10px;
width: 100%;
}
.calendar-table th,
.calendar-table-week th {
padding: 10px;
text-align: center;
}
.calendar-table td,
.calendar-table-week td {
padding: 5px;
text-align: center;
vertical-align: middle;
}
.calendar-table td.current-month,
.calendar-table-week td.current-month {
background-color: #eee;
}
.calendar-table td.clicked,
.calendar-table-week td.clicked {
background-color: #ccc;
}
.calendar-table-week tbody {
display: flex;
flex-direction: row;
justify-content: center;
}
.calendar-table-week tbody tr {
flex: 1;
}
```javascript
let currentMonthIndex = new Date().getMonth();
let currentYear = new Date().getFullYear();
let isWeekView = false;
function renderCalendar(month, year) {
let startDate = new Date(year, month, 1);
let endDate = new Date(year, month + 1, 0);
let daysInMonth = endDate.getDate();
if (isWeekView) {
startDate = new Date(startDate.getTime() - startDate.getDay() * 24 * 60 * 60 * 1000);
endDate = new Date(startDate.getTime() + 6 * 24 * 60 * 60 * 1000);
}
let tbody = document.querySelector('.calendar-table tbody');
tbody.innerHTML = '';
if (isWeekView) {
let tr = document.createElement('tr');
for (let i = 0; i < 7; i++) {
let td = document.createElement('td');
td.textContent = ${startDate.getDate() + i} ${startDate.toLocaleString('default', { month: 'long' })}
;
td.classList.add('current-month');
if (i == 0 || i == 6) {
td.classList.add('weekend');
}
tr.appendChild(td);
}
tbody.appendChild(tr);
} else {
for (let i = 0; i < 6; i++) {
let tr = document.createElement('tr');
for (let j = 0; j < 7; j++) {
let td = document.createElement('td');
let day = i * 7 + j + 1 - startDate.getDay();
if (day > 0 && day <= daysInMonth) {
td.textContent = day;
td.classList.add('current-month');
if (j == 0 || j == 6) {
td.classList.add('weekend');
}
tr.appendChild(td);
} else {
tr.appendChild(document.createElement('td'));
}
}
tbody.appendChild(tr);
}
}
let currentDateCells = document.querySelectorAll(.calendar-table td.current-month
);
currentDateCells.forEach((cell) => {
cell.addEventListener('click', (event) => {
currentDateCells.forEach((c) => {
c.classList.remove('clicked');
});
event.target.classList.add('clicked');
});
});
let currentMonth = document.querySelector('.current-month');
if (isWeekView) {
let startOfWeek = new Date(startDate.getTime());
let endOfWeek = new Date(endDate.getTime());
if (startOfWeek.getMonth() !== endOfWeek.getMonth()) {
currentMonth.textContent = ${startOfWeek.toLocaleString('default', { month: 'short' })} ${startOfWeek.getDate()} - ${endOfWeek.toLocaleString('default', { month: 'short' })} ${endOfWeek.getDate()}
;
} else {
currentMonth.textContent = ${startOfWeek.toLocaleString('default', { month: 'short' })} ${startOfWeek.getDate()} - ${endOfWeek.getDate()}
;
}
} else {
currentMonth.textContent = ${year} - ${startDate.toLocaleString('default', { month: 'long' })}
;
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:CSS 制作有弹性的日历表 - Python技术站