基本上我想了解一些日历知识,日历从谷歌获取事件,但这不是问题。那部分已经完成了。我有这个逻辑,但我无法实现。所需的行为是仅显示未来日期,例如:我们现在是 2024 年 7 月,因此在选择 2024 年时的月份下拉列表中,它应该只显示当前月份及以后的月份,而当选择当前年份之后的任何其他年份时,它应该显示所有月份。这部分运作良好。 现在最大的问题是,当我查看例如 2025 年 3 月(即当年的一年和本月的前一个月)时,如果我尝试将视图切换到 2024 年,则月份下拉列表应默认为 7 月(当前月份),并且与日历渲染相关的变量也应该更新。但这并没有发生,它会转到下拉列表中不存在的选项。我已经寻找并尝试了几个小时,所以我来到 stackoverflow 希望找到解决方案。抱歉,我很累,我可能写了一些令人困惑的事情,所以问我一些事情,我显然很乐意回复!预先感谢。
function populateMonths() {
const selectMonth = document.getElementById('selectMonth');
const currentYear = new Date().getFullYear();
const currentMonth = new Date().getMonth();
const months = [
'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho',
'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'
];
selectMonth.innerHTML = ''; // Clear existing options
let startMonth = 0;
if (selectedYear === currentYear) {
startMonth = currentMonth; // Show from current month onwards
}
console.log(`currentYear: ${currentYear}`);
console.log(`currentMonth: ${currentMonth}`);
console.log(`selectedYear: ${selectedYear}`);
console.log(`selectedMonth: ${selectedMonth}`);
console.log(`startMonth: ${startMonth}`);
months.slice(startMonth).forEach((month, index) => {
const monthIndex = startMonth + index;
const option = document.createElement('option');
option.value = monthIndex; // Adjust value to reflect actual month index
option.textContent = months[monthIndex];
selectMonth.appendChild(option);
});
selectMonth.selectedIndex = selectedMonth - startMonth;
console.log(`Final selectedIndex: ${selectMonth.selectedIndex}`);
}
function populateYears() {
const selectYear = document.getElementById('selectYear');
const currentYear = new Date().getFullYear();
const yearsToShow = 3; // Number of years to show, starting from the current year
selectYear.innerHTML = ''; // Clear existing options
for (let i = 0; i < yearsToShow; i++) {
const year = currentYear + i;
const option = document.createElement('option');
option.value = year;
option.textContent = year;
selectYear.appendChild(option);
}
selectYear.value = selectedYear;
}
function changeMonth() {
selectedMonth = parseInt(document.getElementById('selectMonth').value);
renderCalendar(selectedYear, selectedMonth);
}
function changeYear() {
selectedYear = parseInt(document.getElementById('selectYear').value);
populateMonths();
renderCalendar(selectedYear, selectedMonth);
}
function renderCalendar(year, month) {
const calendar = document.getElementById('calendar');
calendar.innerHTML = '';
const firstDayOfMonth = new Date(year, month, 1);
const lastDayOfMonth = new Date(year, month + 1, 0);
const daysInMonth = lastDayOfMonth.getDate();
const startingDay = firstDayOfMonth.getDay(); // 0 (Sunday) to 6 (Saturday)
const daysOfWeek = ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'];
// Create header row for days of the week
for (let day = 0; day < 7; day++) {
const cell = document.createElement('div');
cell.classList.add('cell', 'header-cell');
cell.textContent = daysOfWeek[day];
calendar.appendChild(cell);
}
// Create blank cells for the days before the first day of the month
for (let i = 0; i < startingDay; i++) {
const cell = document.createElement('div');
cell.classList.add('cell', 'empty-cell');
calendar.appendChild(cell);
}
// Create cells for each day in the month
for (let i = 1; i <= daysInMonth; i++) {
const date = new Date(year, month, i);
const dateString = formatDate(date); // Format date to 'YYYY-MM-DD'
const cell = document.createElement('div');
cell.classList.add('cell');
cell.textContent = i;
const dayEvents = events.filter(event => event.date === dateString);
if (isFullyBooked(dateString)) {
cell.classList.add('booked');
cell.title = 'Totalmente reservado';
} else if (isHalfBooked(dayEvents)) {
cell.classList.add('half-booked');
cell.title = 'Parcialmente reservado';
cell.addEventListener('mouseover', () => showAvailableHoursTooltip(cell, dayEvents));
cell.addEventListener('mouseout', hideTooltip);
} else {
cell.classList.add('available');
cell.title = 'Disponível';
}
calendar.appendChild(cell);
}
}
希望这有帮助,代码比我想象的要简单得多。尝试一下 select 以查看功能,以帮助您了解此代码的作用。我还没有实现填充年,所以我认为这已经是正确的。您可以将事件侦听器转换为原始代码中相应的changeMonth 和changeYears 函数。下面的代码只是帮助您让选择功能按您的预期工作。
const months = [
'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho',
'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'
]
const selectMonth = document.getElementById('selectMonth')
const selectYear = document.getElementById('selectYear')
function filteredMonths(year) {
const currentYear = new Date().getFullYear();
const currentMonth = new Date().getMonth();
if (year > currentYear) return months // return all months if future year
return months.slice(currentMonth, months.length)
}
let lastMonthSelected = null // helps with month memory
function populateMonths(year) {
const validMonths = filteredMonths(year)
const currentMonth = new Date().getMonth();
selectMonth.innerHTML = ''
validMonths.forEach(monthName => {
const option = document.createElement('option');
option.value = months.indexOf(monthName);
option.textContent = monthName
selectMonth.appendChild(option);
});
// if month = 'Outubro' and year change to 2025, stay selected on 'Outubro' still
if (lastMonthSelected && validMonths.indexOf(lastMonthSelected) > -1) {
selectMonth.selectedIndex = validMonths.indexOf(lastMonthSelected);
return
}
const currentMonthIndex = validMonths.indexOf(months[currentMonth])
const startIndex = currentMonthIndex > -1 ? currentMonthIndex : 0
selectMonth.selectedIndex = startIndex;
lastMonthSelected = months[currentMonth]
}
function updateMonthOptions() {
const year = selectYear.value || 2024; // set defaults too
populateMonths(year)
// you dont need to store the selected year or month in a variable unless you need it for another part of your program, but if you did need it, add it here
}
selectYear.addEventListener('change', updateMonthOptions);
selectMonth.addEventListener('change', () => {
lastMonthSelected = selectMonth.options[selectMonth.selectedIndex].text
});
updateMonthOptions() // call once in beginning to set defaults
<select id="selectYear">
<option value="2024">2024</option>
<option value="2025">2025</option>
<option value="2026">2026</option>
</select>
<select id="selectMonth">
<!-- Options will be dynamically populated -->
</select>