提问人:Pablo Escobard 提问时间:11/17/2023 最后编辑:YogiPablo Escobard 更新时间:11/17/2023 访问量:54
Javascript DOM 中的按钮 addeventlisteners 问题
Problem with buttons addeventlisteners in Javascript DOM
问:
我正在尝试创建一个日历,我很久以前就用另一种语言编写了代码,但我的公司网站实际上是 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 和 CSS 已经完整了,这里是完整的 javascript,所以你可以试试 ''program'':
代码片段
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();
#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;
}
<div id="inventory-grid"></div>
<div id="ski-details"></div>
答:
0赞
Nick Friesen
11/17/2023
#1
我建议将按钮 eventListeners 替换为以下内容:
prevMonthButton.onclick = () => showPreviousMonth(calendarContainer, monthDisplay);
nextMonthButton.onclick = () => showNextMonth(calendarContainer, monthDisplay);
添加这些 onclick 属性在功能上执行相同的操作,但将代码添加到按钮元素本身。这样,您可以查看问题是否出在按钮上,是否出在它们正在调用的函数上,或者完全是其他问题。
(您也不需要调用这些按钮中的任何一个,因为该函数会在 和updateCalendar()
showPreviousMonth()
showNextMonth()
)
这仍然可能在您的代码中触发错误,因为我看到您很可能仍想要修复的一些地方,但这应该有助于解决您请求的特定问题。
评论
0赞
Pablo Escobard
11/17/2023
嗨,尼克!非常感谢您的回答,我尝试了通过简单地更改事件侦听器来快速修复,但它们仍然什么也没做。我认为 Yogi 至少有一部分答案,我将按钮附加为 html 似乎正在将所有听众删除到它们上!我试图弄清楚我是否以错误的方式处理这个问题,或者我是否只需要稍后/在其他地方宣布事件!再次感谢这个社区,这是我的第一个问题,显然要简明扼要:)并不容易
0赞
Nick Friesen
11/18/2023
我想说我的两分钱是首先在 HTML 中构建 HTML 结构,然后使用 JavaScript 和 CSS 隐藏和显示 HTML。不过,你可以按照你目前的方式去做,所以一定要做最适合你的事情。
0赞
Pablo Escobard
11/22/2023
我知道我基本上没有在 HTML 中构建任何东西......
评论
showSkiDetails