Вопрос или проблема
Я разрабатываю календарь для школьного проекта, однако у меня возникла проблема, которую я не могу решить, и мои поиски не привели к успеху. Когда я генерирую месяц и нажимаю, чтобы перейти к следующему месяцу, таблица накладывается, из-за чего последующие месяцы становятся багованными.
Вот мой код на HTML и JavaScript.
// Добавляет событие, которое срабатывает, когда содержимое документа полностью загружено
document.addEventListener('DOMContentLoaded', function() {
// Массив, содержащий названия месяцев на португальском
const monthsPt = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'];
const tableDays = document.getElementById('dias'); // Получает таблицу дней по ID
// Функция для генерации дней календаря для определенного месяца и года
function GetDaysCalendar(month, year) {
// Обновляет отображаемый месяц и год
document.getElementById('mes').innerHTML = monthsPt[month];
document.getElementById('ano').innerHTML = year;
// Вычисляет первый день недели месяца и последний день месяца
let firstDayOfWeek = new Date(year, month, 1).getDay() - 1;
let getLastDayThisMonth = new Date(year, month + 1, 0).getDate();
// Цикл для заполнения дней таблицы
for (var i = -firstDayOfWeek, index = 0; i < (42 - firstDayOfWeek); i++, index++) {
let dt = new Date(year, month, i); // Создает объект даты для текущего дня цикла
let dtNow = new Date(); // Текущая дата
var dayTable = tableDays.getElementsByTagName('td')[index]; // Получает соответствующую ячейку таблицы
var today = new Date();
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0'); // Январь - 0!
let currentDay = parseInt(dd);
let currentMounth = parseInt(mm) - 1;
// Убирает классы для предыдущего месяца, следующего месяца и текущего дня
dayTable.classList.remove('mes-anterior');
dayTable.classList.remove('mes-proximo');
dayTable.classList.remove('dia-atual');
dayTable.innerHTML = dt.getDate(); // Устанавливает номер дня в ячейке
dayTable.addEventListener('click', function() {
console.log("тривилин");
console.log(dt.getDate());
console.log(currentDay);
console.log(dt.getMonth());
console.log(currentMounth);
if ((dt.getDate() >= currentDay && dt.getMonth() == currentMounth) || dt.getMonth() > currentMounth) {
const modal = document.getElementById("ModalAceito");
const span = document.getElementsByClassName("close")[0];
modal.style.display = "block";
span.onclick = function() {
modal.style.display = "none";
}
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
} else {
const modall = document.getElementById("ModalError");
const spann = document.getElementsByClassName("closeError")[0];
modall.style.display = "block";
spann.onclick = function() {
modall.style.display = "none";
}
window.onclick = function(event) {
if (event.target == modall) {
modall.style.display = "none";
}
}
}
});
// Проверяет, совпадает ли текущая дата с датой цикла
if (dt.getFullYear() == dtNow.getFullYear() && dt.getMonth() == dtNow.getMonth() && dt.getDate() == dtNow.getDate()) {
dayTable.classList.add('dia-atual'); // Добавляет класс для текущего дня
}
// Добавляет класс для дней из предыдущего месяца
if (i < 1) {
dayTable.classList.add('mes-anterior');
}
// Добавляет класс для дней из следующего месяца
if (i > getLastDayThisMonth) {
dayTable.classList.add('mes-proximo');
}
}
}
// Получает текущую дату
let now = new Date();
let month = now.getMonth(); // Текущий месяц
let year = now.getFullYear(); // Текущий год
GetDaysCalendar(month, year); // Генерирует календарь для текущего месяца
// Получает кнопки для навигации между месяцами
const buttonNext = document.getElementById('btn_prev');
const buttonPrevious = document.getElementById('btn_ant');
// Событие для кнопки "следующий месяц"
buttonNext.onclick = function() {
month++; // Переходит к следующему месяцу
if (month >= 12) { // Если превышает декабрь
month = 0; // Сбрасывает до января
year++; // Переходит к следующему году
}
GetDaysCalendar(month, year); // Обновляет календарь
}
// Событие для кнопки "предыдущий месяц"
buttonPrevious.onclick = function() {
month--; // Переходит к предыдущему месяцу
if (month < 0) { // Если меньше января
month = 11; // Сбрасывает до декабря
year--; // Переходит к предыдущему году
}
GetDaysCalendar(month, year); // Обновляет календарь
}
});
<!-- Указывает браузеру, какая версия HTML используется -->
<!DOCTYPE html>
<!-- Открывающий HTML, установка языка на pt -->
<html lang="pt">
<!-- Открытие заголовка сайта -->
<head>
<meta charset="UTF-8">
<!-- Импорт стиля css в код html -->
<link rel="stylesheet" type="text/css" href="https://stackoverflow.com/questions/79024966/C:\Users\Aluno\Desktop\PAP\Css\Estilo.css">
<!-- Импорт кода на JavaScript в код html -->
<script type="text/javascript" src="C:\Users\Aluno\Desktop\PAP\Script\Script.js"></script>
<!-- Устанавливает заголовок сайта для Registo de Salas -->
<title> Registo de Salas </title>
<!-- Закрытие заголовка сайта -->
</head>
<!-- Открытие тела сайта -->
<body>
<!-- Создание заголовка в начале сайта с именем "Registo de Salas" -->
<h1> Registo de Salas </h1>
<!-- Создание div и определение его как класс Conteudo -->
<div class="Conteudo">
<!-- Создание div и определение его с классом под названием "Calendario"-->
<div class="Calendario">
<!-- Открытие заголовка-->
<header>
<!-- Создание подписи и определение ее идентификатора для mes -->
<h2 id="mes">Апрель</h2>
<!-- Создание ссылки и указание ее как класс btn-ant с идентификатором btn_prev -->
<a class="btn-ant" id="btn_ant">
<</a>
<!-- Создание ссылки и указание ее как класс btn-pro с идентификатором btn_next -->
<a class="btn-pro" id="btn_prev">></a>
<!-- Закрытие заголовка -->
</header>
<!-- Создание таблицы для формирования календаря -->
<!-- Я создал эту таблицу на основе того, что я знаю о HTML на данный момент, если это станет используемым проектом, можно реализовать более эффективный метод, и я прошу прощения за путаницу, которая последует, я действительно импровизирую в этой части.-->
<table>
<!-- Открывает заголовок таблицы -->
<thead>
<!-- Создание строки в таблице -->
<tr>
<!-- Эта часть кода служит для отображения дней недели в верхней части календаря, если кто-то изменит это, возможно, придется изменить и индекс страницы. -->
<td>Вс</td>
<td>Пн</td>
<td>Вт</td>
<td>Ср</td>
<td>Чт</td>
<td>Пт</td>
<td>Сб</td>
<!-- Закрытие строки таблицы -->
</tr>
<!-- Закрытие заголовка таблицы -->
</thead>
<!-- Создание тела таблицы и установка его идентификатора как dias -->
<tbody id="dias">
<!-- Строки кода ниже служат только для загрузки строк календаря и создания их соответствующих пространств, дни заменяются кодом, написанным на JavaScript -->
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
</tr>>
<!-- Закрытие тела таблицы -->
</tbody>
<!-- Закрытие таблицы -->
</table>
<!-- Открытие нижнего колонтитула -->
<footer>
<!-- Использование тега h2 для размещения года, его идентификатор года связан с тем, что так проще заменить его в JavaScript -->
<h2 id="ano">2020</h2>
<!-- Закрытие нижнего колонтитула -->
</footer>
<!-- Структура модального окна -->
<div id="ModalAceito" class="modal">
<div class="modal-content">
<table>
<span class="close">×</span>
<td> Зал тик 1</td>
</table>
</div>
</div>
<div id="ModalError" class="modal">
<div class="modal-content">
<span class="closeError">×</span>
<h1> Невозможно сделать назначение</h1>
</div>
</div>
<!-- Закрытие div -->
</div>
<!-- Закрытие div -->
</div>
<!-- Закрытие тела сайта -->
</body>
<!-- Закрытие HTML -->
</html>
Я уже пробовал спрашивать своих учителей и смотрел, где находил что-то об этом.
Ответ или решение
Ваш код создаёт календари, но проблема с наложением значений в таблице может быть связана с тем, что вы не очищаете содержимое ячеек таблицы перед заполнением их новыми данными. Это может привести к тому, что старые значения остаются в ячейках, и при переключении между месяцами они накладываются на новые.
Для решения этой проблемы следует добавить явное очищение содержимого ячеек таблицы перед их заполнением новыми значениями. Давайте рассмотрим, как это можно сделать.
Ниже приводится обновленная версия вашей функции GetDaysCalendar
, в которой я добавил логику, очищающую таблицу перед добавлением новых значений:
function GetDaysCalendar(month, year) {
// Обновляет отображаемый месяц и год
document.getElementById('mes').innerHTML = monthsPt[month];
document.getElementById('ano').innerHTML = year;
// Вычисляет первый день недели месяца и последний день месяца
let firstDayOfWeek = new Date(year, month, 1).getDay() - 1;
let getLastDayThisMonth = new Date(year, month + 1, 0).getDate();
// Очищаем предыдущие значения ячеек таблицы
const dayCells = tableDays.getElementsByTagName('td');
for (let cell of dayCells) {
cell.innerHTML = ''; // Очистка содержимого ячейки
}
// Заполнение дней в таблице
for (var i = -firstDayOfWeek, index = 0; i < (42 - firstDayOfWeek); i++, index++) {
let dt = new Date(year, month, i); // Создаем объект даты для текущего дня в цикле
let dtNow = new Date(); // Текущая дата
var dayTable = tableDays.getElementsByTagName('td')[index]; // Получаем соответствующую ячейку таблицы
var today = new Date();
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0'); // Январь 0!
let currentDay = parseInt(dd);
let currentMounth = parseInt(mm) - 1;
// Убираем классы для предыдущего месяца, следующего месяца и текущего дня
dayTable.classList.remove('mes-anterior');
dayTable.classList.remove('mes-proximo');
dayTable.classList.remove('dia-atual');
dayTable.innerHTML = dt.getDate(); // Устанавливает номер дня в ячейке
dayTable.addEventListener('click', function() {
// Ваша логика для обработки клика по дню
});
// Проверяем совпадение с текущей датой
if (dt.getFullYear() == dtNow.getFullYear() && dt.getMonth() == dtNow.getMonth() && dt.getDate() == dtNow.getDate()) {
dayTable.classList.add('dia-atual'); // Добавляем класс для текущего дня
}
// Добавляем класс для дней предыдущего месяца
if (i < 1) {
dayTable.classList.add('mes-anterior');
}
// Добавляем класс для дней следующего месяца
if (i >= getLastDayThisMonth) {
dayTable.classList.add('mes-proximo');
}
}
}
Обратите внимание на блок кода, который очищает содержимое ячеек таблицы:
// Очищаем предыдущие значения ячеек таблицы
const dayCells = tableDays.getElementsByTagName('td');
for (let cell of dayCells) {
cell.innerHTML = ''; // Очистка содержимого ячейки
}
Эта часть кода будет выполнена каждый раз, когда вы меняете месяц, гарантируя, что все значения в таблице очищаются перед тем, как заполнить её новыми значениями.
Также убедитесь, что ваши кнопки для навигации между месяцами правильно работают и запускают функцию GetDaysCalendar
с корректными аргументами.
Данная модификация должна решить вашу проблему с наложением значений в таблице. Надеюсь, это поможет вам успешно завершить ваш школьный проект!