提问人:Harshvardhan Sinha 提问时间:8/12/2023 最后编辑:Don't PanicHarshvardhan Sinha 更新时间:8/13/2023 访问量:33
对于循环在预订网站中不起作用,日期不是连续的
For loop not working in booking site, the dates are not serial
问:
我正在尝试制作一个预订网站,然后出现了一个问题,即 for 循环正在工作或我的逻辑错误。
我期待(旧版本代码的屏幕截图):
输出是什么(新版本的屏幕截图):
此外,我正在为此使用 PHP,并且正在按预期工作。当我尝试发出 AJAX 请求时,可能出了点问题。check_date.php
// JavaScript code for generating the calendar and handling month navigation
const calendarContainer = document.getElementById("calendar");
const prevMonthBtn = document.getElementById("prevMonth");
const nextMonthBtn = document.getElementById("nextMonth");
const currentMonthYear = document.getElementById("currentMonthYear");
const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const months = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
const currentDate = new Date();
let currentMonth = currentDate.getMonth();
let currentYear = currentDate.getFullYear();
function generateCalendar() {
const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();
const firstDayIndex = new Date(currentYear, currentMonth, 1).getDay();
calendarContainer.innerHTML = "";
// Display days of the week at the top of the calendar
for (const dayOfWeek of daysOfWeek) {
const dayOfWeekDiv = document.createElement("div");
dayOfWeekDiv.classList.add("day");
dayOfWeekDiv.textContent = dayOfWeek;
calendarContainer.appendChild(dayOfWeekDiv);
}
for (let i = 0; i < firstDayIndex; i++) {
const dayDiv = document.createElement("div");
dayDiv.classList.add("day");
calendarContainer.appendChild(dayDiv);
}
for (let i = 1; i <= daysInMonth; i++) {
const dayDiv = document.createElement("a");
dayDiv.href = "entry.php";
let __ryear = currentYear.toString();
let __rmonth = currentMonth.toString();
let daI = i.toString();
let result1 = __ryear.concat(__rmonth);
let result2 = result1.concat(daI);
// let ruiue = result2;
// let date6969 = i;
// AJAX request to check if the date exists in the database
let xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost/irctclogin/check_date.php?date=" + result2, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
let response = xhr.responseText;
if (response == "exists") {
// Date exists in the database, continue the program
let bookStatus = "booked";
dayDiv.classList.add("day", result2, bookStatus);
dayDiv.textContent = i;
calendarContainer.appendChild(dayDiv);
// dayDiv.value = i;
}
else {
let bookStatus = "available";
dayDiv.classList.add("day", result2, bookStatus);
dayDiv.textContent = i;
calendarContainer.appendChild(dayDiv);
// dayDiv.value = i;
// console.log(i);
}
}
}
xhr.send();
}
currentMonthYear.textContent = `${months[currentMonth]} ${currentYear}`;
// console.log(`${months[currentMonth]} ${currentYear}`);
}
prevMonthBtn.addEventListener("click", () => {
if (currentMonth === 0) {
currentMonth = 11;
currentYear--;
} else {
currentMonth--;
}
generateCalendar();
});
nextMonthBtn.addEventListener("click", () => {
if (currentMonth === 11) {
currentMonth = 0;
currentYear++;
} else {
currentMonth++;
}
generateCalendar();
});
generateCalendar();
答:
您的天数显示为乱序的原因是,它们是按照 AJAX 请求完成的顺序生成的。仅仅因为您按顺序触发了多个 AJAX 请求,并不意味着它们将按照您启动它们的顺序完成。因此,如果请求 #10 在请求 #9 之前完成,则每月 10 日的单元格将出现在第 9 个单元格之前。
这是一个工作片段,其中包含一些非常基本的 CSS,其中注释掉了 AJAX,这表明在没有 AJAX 的情况下生成日历可以正常工作。
const calendarContainer = document.getElementById("calendar");
const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const months = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
const currentDate = new Date();
let currentMonth = currentDate.getMonth();
let currentYear = currentDate.getFullYear();
function generateCalendar() {
const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();
const firstDayIndex = new Date(currentYear, currentMonth, 1).getDay();
calendarContainer.innerHTML = "";
// Display days of the week at the top of the calendar
for (const dayOfWeek of daysOfWeek) {
const dayOfWeekDiv = document.createElement("div");
dayOfWeekDiv.classList.add("day");
dayOfWeekDiv.textContent = dayOfWeek;
calendarContainer.appendChild(dayOfWeekDiv);
}
for (let i = 0; i < firstDayIndex; i++) {
const dayDiv = document.createElement("div");
dayDiv.classList.add("day");
calendarContainer.appendChild(dayDiv);
}
for (let i = 1; i <= daysInMonth; i++) {
const dayDiv = document.createElement("a");
dayDiv.href = "entry.php";
let __ryear = currentYear.toString();
let __rmonth = currentMonth.toString();
let daI = i.toString();
let result1 = __ryear.concat(__rmonth);
let result2 = result1.concat(daI);
// AJAX request to check if the date exists in the database
// let xhr = new XMLHttpRequest();
// xhr.open("GET", "http://localhost/irctclogin/check_date.php?date=" + result2, true);
// xhr.onreadystatechange = function() {
// if (xhr.readyState == 4 && xhr.status == 200) {
// let response = xhr.responseText;
// if (response == "exists") {
//
// // Date exists in the database, continue the program
// let bookStatus = "booked";
// dayDiv.classList.add("day", result2, bookStatus);
// dayDiv.textContent = i;
// calendarContainer.appendChild(dayDiv);
// // dayDiv.value = i;
//
// }
// else {
let bookStatus = "available";
dayDiv.classList.add("day", result2, bookStatus);
dayDiv.textContent = i;
calendarContainer.appendChild(dayDiv);
// // dayDiv.value = i;
// // console.log(i);
// }
// }
// }
// xhr.send();
}
}
generateCalendar();
a {
display: inline-block;
width: 50px;
border: 1px solid black;
}
<div id="calendar"></div>
一个更好的方法是独立于AJAX生成日历,例如在页面加载时,就像一个等待数据的空模板一样。您已经根据日期(在代码中)为每个单元格指定了一个唯一的类。因此,当您获得 2023 年 7 月 23 日的 AJAX 结果时,您可以使用如下选择器找到需要更新的单元格:result2
// Say your AJAX returns some data with a value like 'date"
let cell = document.getElementsByClassName(date);
cell.classList.add('booked');
但是,在当月的每一天都触发一个单独的 AJAX 请求是非常低效的 - 完成这个月需要很长时间,而且似乎很有可能某些请求无法完成或被拒绝。在几分之一秒内收到 31 个请求似乎是因看起来像机器人而被阻止的好方法。
一个更好的选择是让 AJAX 一次返回一整月的数据。显然,您必须更新您的 PHP,并以可以表示多天的格式返回数据,每天都有一个预订状态。例如:
// Your PHP code, inside some kind of loop here, iterating over days in the month ..
$month[] = [
'date' => $date,
'state' => $state // 'booked' or whatever ...
];
// Loop finished, now return data as JSON
header('Content-type: application/json');
echo json_encode($month);
现在,您的 Javascript 可以通过 1 次 AJAX 调用来处理整个月。您只需要遍历 JSON 响应,并使用正确的状态更新每个单元格。
评论