我正在尝试创建一个日历,我很久以前就用另一种语言编写了代码,但我的公司网站实际上是用 javascript 和 HTML 编写的,所以就是这样。
我认为我遇到了一个非常基本的问题(尽管我无法解决它)。我正在尝试在日历的标题中创建按钮,该按钮本身出现在所述页面的弹出窗口中。经过一番尝试和错误后,我设法使按钮出现...但我创建的事件侦听器似乎根本不起作用!
我已经尝试了一些调试,正如您将在代码中看到的那样,有些是//
对于初学者来说,这里是我使用按钮(箭头)创建“标题”的地方
function createCalendarHeader() {
const calendarHeader = document.createElement('div');
calendarHeader.classList.add('calendar-header');
// Add the month display
const monthDisplay = document.createElement('div');
calendarHeader.appendChild(monthDisplay);
// Add previous month arrow button
prevMonthButton = document.createElement('button');
prevMonthButton.innerHTML = '<';
prevMonthButton.addEventListener('click', () => { //<-- Here are the event listeners.
showPreviousMonth(calendarContainer, monthDisplay);
updateCalendar(calendarContainer, monthDisplay);
});
calendarHeader.appendChild(prevMonthButton);
// Add next month arrow button
nextMonthButton = document.createElement('button');
nextMonthButton.innerHTML = '>';
nextMonthButton.addEventListener('click', () => { //<-- Here are the event listeners.
showNextMonth(calendarContainer, monthDisplay);
updateCalendar(calendarContainer, monthDisplay);
console.log('Button next clicked');
});
console.log('Buttons created');
calendarHeader.appendChild(nextMonthButton);
return {
calendarHeader,
monthDisplay,
prevMonthButton,
nextMonthButton
};
}
之后,我尝试用日历将其全部包裹起来,并使用此函数来调用 HTML 中的弹出窗口,我一直在想这可能是它搞砸的地方......:
function showSkiDetails(skiId) {
const selectedSki = skiInventory.find((ski) => ski.id === skiId);
// Create a fake pop-up container
const fakePopup = document.createElement('div');
fakePopup.classList.add('fake-popup');
// Create a calendar container
const calendarContainer = createCalendarContainer();
// Create a calendar header
const { calendarHeader, monthDisplay, prevMonthButton, nextMonthButton } = createCalendarHeader();
// Append the header to the container
calendarContainer.appendChild(calendarHeader);
// Add days to the calendar
updateCalendar(calendarContainer, monthDisplay);
// Create a container for the header and buttons
const headerButtonContainer = document.createElement('div');
headerButtonContainer.classList.add('header-button-container');
// Append the buttons and header to the container
headerButtonContainer.appendChild(prevMonthButton);
headerButtonContainer.appendChild(monthDisplay);
headerButtonContainer.appendChild(nextMonthButton);
// Populate the fake pop-up with ski details and calendar
fakePopup.innerHTML = `
<div class="popup-content">
<span class="close" onclick="closeFakePopup()">×</span>
<h2>${selectedSki.model}</h2>
<p>Status: ${selectedSki.status}</p>
<p>Location: ${selectedSki.location}</p>
<div class="calendar-container">${headerButtonContainer.outerHTML}${calendarContainer.outerHTML}</div>
</div>
`;
// Append the fake pop-up to the body
document.body.appendChild(fakePopup);
}
然后我们让弹出窗口简单地出现在 HTML 中:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Ski Rental Management</title>
</head>
<body>
<div id="inventory-grid"></div>
<div id="ski-details"></div>
<script src="main.js"></script>
</body>
</html>
这是CSS
#inventory-grid {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.ski-card {
border: 1px solid #ccc;
padding: 10px;
width: 200px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
margin-bottom: 10px;
display: flex;
flex-direction: column;
}
.ski-card p {
margin: 0; /* Remove default margins for <p> elements */
}
.ski-card button {
margin-top: auto; /* Push the button to the bottom of the card */
}
.fake-popup {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
}
.popup-content {
background: #fff;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
position: relative;
}
.close {
position: absolute;
top: 10px;
right: 10px;
font-size: 20px;
cursor: pointer;
}
.calendar {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 5px;
text-align: center;
}
.calendar-header {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.calendar-day {
padding: 5px;
border: 1px solid #ccc;
cursor: pointer;
}
.calendar-day:hover {
background-color: #f0f0f0;
}
我尝试添加一堆日志,但事件侦听器中的所有日志都不起作用,尽管其他所有内容似乎都已正确调用和创建......
感谢您的帮助!
HTML 和 CSS 已经完整,这里是完整的 javascript,所以你可以在 codepen 中尝试“程序”:
const skiInventory = [
{ id: 1, model: 'Ski Model 1', status: 'available', location: 'Shop A' },
{ id: 2, model: 'Ski Model 2', status: 'rented', location: 'Customer X' },
{ id: 3, model: 'Ski Model 3', status: 'available', location: 'Shop A' },
// ... add more ski data as needed
];
// Function to render the inventory grid
function renderInventory() {
const inventoryGrid = document.getElementById('inventory-grid');
inventoryGrid.innerHTML = '';
// Clear previous content
skiInventory.forEach(ski => {
const skiCard = document.createElement('div');
skiCard.classList.add('ski-card');
skiCard.innerHTML = `
<p>${ski.model}</p>
<p>Status: ${ski.status}</p>
<button onclick="showSkiDetails(${ski.id})">Details</button>
`;
inventoryGrid.appendChild(skiCard);
});
}
//Début de la création du calendrier
let currentMonth = new Date().getMonth();
let currentYear = new Date().getFullYear();
function createCalendarContainer() {
const calendarContainer = document.createElement('div');
calendarContainer.classList.add('calendar');
return calendarContainer;
}
function createCalendarHeader() {
const calendarHeader = document.createElement('div');
calendarHeader.classList.add('calendar-header');
// Add the month display
const monthDisplay = document.createElement('div');
calendarHeader.appendChild(monthDisplay);
// Add previous month arrow button
prevMonthButton = document.createElement('button');
prevMonthButton.innerHTML = '<';
prevMonthButton.addEventListener('click', () => {
showPreviousMonth(calendarContainer, monthDisplay);
updateCalendar(calendarContainer, monthDisplay);
});
calendarHeader.appendChild(prevMonthButton);
// Add next month arrow button
nextMonthButton = document.createElement('button');
nextMonthButton.innerHTML = '>';
nextMonthButton.addEventListener('click', () => {
showNextMonth(calendarContainer, monthDisplay);
updateCalendar(calendarContainer, monthDisplay);
console.log('Boutons next clicked');
});
console.log('Boutons créer');
calendarHeader.appendChild(nextMonthButton);
return { calendarHeader, monthDisplay, prevMonthButton, nextMonthButton };
}
//Fonction qui fait apparaitre la fênetre avec le calendrier,
function showSkiDetails(skiId) {
const selectedSki = skiInventory.find((ski) => ski.id === skiId);
// Create a fake pop-up container
const fakePopup = document.createElement('div');
fakePopup.classList.add('fake-popup');
// Create a calendar container
const calendarContainer = createCalendarContainer();
// Create a calendar header
const { calendarHeader, monthDisplay, prevMonthButton, nextMonthButton } = createCalendarHeader();
// Append the header to the container
calendarContainer.appendChild(calendarHeader);
// Add days to the calendar
updateCalendar(calendarContainer, monthDisplay);
// Create a container for the header and buttons
const headerButtonContainer = document.createElement('div');
headerButtonContainer.classList.add('header-button-container');
// Append the buttons and header to the container
headerButtonContainer.appendChild(prevMonthButton);
headerButtonContainer.appendChild(monthDisplay);
headerButtonContainer.appendChild(nextMonthButton);
// Populate the fake pop-up with ski details and calendar
fakePopup.innerHTML = `
<div class="popup-content">
<span class="close" onclick="closeFakePopup()">×</span>
<h2>${selectedSki.model}</h2>
<p>Status: ${selectedSki.status}</p>
<p>Location: ${selectedSki.location}</p>
<div class="calendar-container">${headerButtonContainer.outerHTML}${calendarContainer.outerHTML}</div>
</div>
`;
// Append the fake pop-up to the body
document.body.appendChild(fakePopup);
}
function onCalendarDayClick(day) {
// Handle the calendar day click event
console.log('Selected day:', day);
// You can add your logic here, such as updating the selected date in your application.
}
function showPreviousMonth(calendarContainer, monthDisplay) {
// Show the previous month
currentMonth -= 1;
if (currentMonth < 0) {
currentMonth = 11;
currentYear -= 1;
}
updateCalendar(calendarContainer, monthDisplay);
}
function showNextMonth(calendarContainer, monthDisplay) {
// Show the next month
currentMonth += 1;
if (currentMonth > 11) {
currentMonth = 0;
currentYear += 1;
}
console.log(currentMonth)
updateCalendar(calendarContainer, monthDisplay);
}
function updateCalendar(calendarContainer, monthDisplay) {
// Update the calendar with the new month and year
calendarContainer.innerHTML = ''; // Clear the existing calendar
console.log('update calendar');
// Add days of the week
const daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
daysOfWeek.forEach((day) => {
const dayOfWeek = document.createElement('div');
dayOfWeek.classList.add('calendar-day', 'header-day');
dayOfWeek.textContent = day;
calendarContainer.appendChild(dayOfWeek);
});
// Add the month display
monthDisplay.textContent = `${getMonthName(currentMonth)} ${currentYear}`;
// Get the first day of the month
const firstDayOfMonth = new Date(currentYear, currentMonth, 1).getDay();
// Add days to the calendar
const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();
for (let i = 1; i <= daysInMonth + firstDayOfMonth; i++) {
const calendarDay = document.createElement('div');
calendarDay.classList.add('calendar-day');
if (i > firstDayOfMonth) {
const dayOfMonth = i - firstDayOfMonth;
calendarDay.textContent = dayOfMonth;
calendarDay.addEventListener('click', () => onCalendarDayClick(dayOfMonth));
}
calendarContainer.appendChild(calendarDay);
}
}
function getMonthName(monthIndex) {
const monthNames = [
'January', 'February', 'March', 'April',
'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December'
];
return monthNames[monthIndex];
}
// Function to close the fake pop-up
function closeFakePopup() {
const fakePopup = document.querySelector('.fake-popup');
fakePopup.parentNode.removeChild(fakePopup);
}
// Function to handle the check-out process
function checkOut(skiId) {
// Implement logic to update the status of the selected ski to 'rented'
renderInventory(); // Refresh the inventory grid
}
// Function to handle the check-in process
function checkIn(skiId) {
// Implement logic to update the status of the selected ski to 'available'
renderInventory(); // Refresh the inventory grid
}
// Initial rendering of the inventory
renderInventory();
我建议将按钮事件监听器替换为以下内容:
prevMonthButton.onclick = () => showPreviousMonth(calendarContainer, monthDisplay);
nextMonthButton.onclick = () => showNextMonth(calendarContainer, monthDisplay);
添加这些 onclick 属性在功能上执行相同的操作,但将代码添加到按钮元素本身。通过这种方式,您可以查看问题是否出在按钮、它们所调用的函数上,或者完全是其他问题。
(您也不需要为这些按钮调用
updateCalendar()
,因为该函数会在 showPreviousMonth()
和 showNextMonth()
中调用)
这可能仍然会在您的代码中引发错误,因为我看到一些您很可能仍想修复的地方,但这应该有助于解决您请求的特定问题。