Javascript DOM 中添加事件侦听器按钮的问题

问题描述 投票:0回答:1

我正在尝试创建一个日历,我很久以前就用另一种语言编写了代码,但我的公司网站实际上是用 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 = '&gt;';
  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()">&times;</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 = '&lt;';
        prevMonthButton.addEventListener('click', () => {
          showPreviousMonth(calendarContainer, monthDisplay); 
          updateCalendar(calendarContainer, monthDisplay);
       });

    
       calendarHeader.appendChild(prevMonthButton);

        // Add next month arrow button
        nextMonthButton = document.createElement('button');
        nextMonthButton.innerHTML = '&gt;';
        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()">&times;</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();
javascript dom button dom-events addeventlistener
1个回答
0
投票

我建议将按钮事件监听器替换为以下内容:

prevMonthButton.onclick = () => showPreviousMonth(calendarContainer, monthDisplay);
nextMonthButton.onclick = () => showNextMonth(calendarContainer, monthDisplay);

添加这些 onclick 属性在功能上执行相同的操作,但将代码添加到按钮元素本身。通过这种方式,您可以查看问题是否出在按钮、它们所调用的函数上,或者完全是其他问题。

(您也不需要为这些按钮调用

updateCalendar()
,因为该函数会在
showPreviousMonth()
showNextMonth()
中调用)

这可能仍然会在您的代码中引发错误,因为我看到一些您很可能仍想修复的地方,但这应该有助于解决您请求的特定问题。

© www.soinside.com 2019 - 2024. All rights reserved.