首页 > 解决方案 > 使用 onclick 从日历返回日期值

问题描述

我在网上找到了这个日历代码,我希望处理它并在每一天添加一个点击监听器并返回选定的日期,但我无法在代码中找到每一天的代码,因此我不知道如何添加在 onclick 监听器中。

这是代码。

const date = new Date();

const renderCalendar = () => {
  date.setDate(1);

  const monthDays = document.querySelector(".days");

  const lastDay = new Date(
    date.getFullYear(),
    date.getMonth() + 1,
    0
  ).getDate(); 

  const prevLastDay = new Date(
    date.getFullYear(),
    date.getMonth(),
    0
  ).getDate(); 

  const firstDayIndex = date.getDay();

  const lastDayIndex = new Date(
    date.getFullYear(),
    date.getMonth() + 1,
    0
  ).getDay();

  const nextDays = 7 - lastDayIndex - 1;

  const months = [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December",
  ];


  document.querySelector(".date h1").innerHTML = months[date.getMonth()];
  document.querySelector(".date p").innerHTML = new Date().toDateString();

  let days = "";

  for (let x = firstDayIndex; x > 0; x--) {
    days += `<div class="prev-date">${prevLastDay - x + 1}</div>`;
    
  } 

  for (let i = 1; i <= lastDay; i++) {
      if (
        i >= new Date().getDate() &&
        date.getMonth() >= new Date().getMonth()
      ) {
        days += `<div class="green">${i}</div>`;
      } else {
        days += `<div class="red">${i}</div>`;
      }
    }
  

  monthDays.innerHTML = days;

};

document.querySelector(".prev").addEventListener("click", () => {
  date.setMonth(date.getMonth() - 1);
  renderCalendar();
});

document.querySelector(".next").addEventListener("click", () => {
  date.setMonth(date.getMonth() + 1);
  renderCalendar();
});
renderCalendar();
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Quicksand", sans-serif;
  }
  
  html {
    font-size: 62.5%;
  }
  
  .leaves {
    width: 100%;
    /* height: 100vh; */
    background-color: #12121f;
    color: #eee;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  
  .container {
    width: 100%;
    height: 100vh;
    background-color: #12121f;
    color: #eee;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  
  .calendar {
    width: 45rem;
    height: 52rem;
    background-color: #222227;
    box-shadow: 0 0.5rem 3rem rgba(0, 0, 0, 0.4);
  }
  
  .month {
    width: 100%;
    height: 12rem;
    background-color: #167e56;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 2rem;
    text-align: center;
    text-shadow: 0 0.3rem 0.5rem rgba(0, 0, 0, 0.5);
  }
  
  .month i {
    font-size: 2.5rem;
    cursor: pointer;
  }
  
  .month h1 {
    font-size: 3rem;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.2rem;
    margin-bottom: 1rem;
  }
  
  .month p {
    font-size: 1.6rem;
  }
  
  .weekdays {
    width: 100%;
    height: 5rem;
    padding: 0 0.4rem;
    display: flex;
    align-items: center;
  }
  
  .weekdays div {
    font-size: 1.5rem;
    font-weight: 400;
    letter-spacing: 0.1rem;
    width: calc(44.2rem / 7);
    display: flex;
    justify-content: center;
    align-items: center;
    text-shadow: 0 0.3rem 0.5rem rgba(0, 0, 0, 0.5);
  }
  
  .days {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    padding: 0.2rem;
  }
  
  .days div {
    font-size: 1.4rem;
    margin: 0.3rem;
    width: calc(40.2rem / 7);
    height: 5rem;
    display: flex;
    justify-content: center;
    align-items: center;
    text-shadow: 0 0.3rem 0.5rem rgba(0, 0, 0, 0.5);
    transition: background-color 0.2s;
  }
  
  .days div:hover:not(.today) {
    background-color: #262626;
    border: 0.2rem solid #777;
    cursor: pointer;
  }
  
  .prev-date,
  .fcc-other-month { 
    visibility:hidden;
 }
  .next-date {
    opacity: 0.5;
  }
  
  .green {
    background-color: #167e56;
  }

  .red {
    background-color: red;
  }
<div class="leaves">
      <div class="calendar">
        <div class="month">
          <i class="fas fa-angle-left prev"></i>
          <div class="date">
            <h1></h1>
            <p></p>
          </div>
          <i class="fas fa-angle-right next"></i>
        </div>
        <div class="weekdays">
          <div>Sun</div>
          <div>Mon</div>
          <div>Tue</div>
          <div>Wed</div>
          <div>Thu</div>
          <div>Fri</div>
          <div>Sat</div>
        </div>
        <div class="days"></div>
      </div>
    </div>

我知道 div class="green" 正在将今天的颜色更改为绿色,但如果我想将今天前几天的颜色更改为红色,我添加了 div class="red" 但下个月并非所有日子都在绿色。明年一切都会变成红色。我可以知道如何正确更改颜色吗

标签: javascripthtmlcss

解决方案


您正在寻找的循环是这样的:

for (let i = 1; i <= lastDay; i++) {
if (i >= new Date().getDate() &&
    date.getMonth() >= new Date().getMonth()
  ) {
    days += `<div class="green">${i}</div>`;
  } else {
    days += `<div class="red">${i}</div>`;
  }
}

就其div本身而言,您必须添加一个类,比如说day,然后还向它添加某种类型的 data-* ,假设data-date其值将是日期,例如01-01。然后,您可以向该类添加一个单击侦听器day并使用事件的 currentTarget 数据集。

您的代码将是这样的:

const date = new Date();

const renderCalendar = () => {
  date.setDate(1);

  const monthDays = document.querySelector(".days");

  const lastDay = new Date(
    date.getFullYear(),
    date.getMonth() + 1,
    0
  ).getDate(); 

  const prevLastDay = new Date(
    date.getFullYear(),
    date.getMonth(),
    0
  ).getDate(); 

  const firstDayIndex = date.getDay();

  const lastDayIndex = new Date(
    date.getFullYear(),
    date.getMonth() + 1,
    0
  ).getDay();

  const nextDays = 7 - lastDayIndex - 1;

  const months = [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December",
  ];


  document.querySelector(".date h1").innerHTML = months[date.getMonth()];
  document.querySelector(".date p").innerHTML = new Date().toDateString();

  let days = "";

  for (let x = firstDayIndex; x > 0; x--) {
    days += `<div class="prev-date">${prevLastDay - x + 1}</div>`;
    
  } 

  for (let i = 1; i <= lastDay; i++) {
      if (
        i >= new Date().getDate() &&
        date.getMonth() >= new Date().getMonth()
      ) {
        days += `<div class="green day" data-date="${i}-${date.getMonth() + 1}">${i}</div>`;
      } else {
        days += `<div class="red day" data-date="${i}-${date.getMonth() + 1}">${i}</div>`;
      }
    }

  monthDays.innerHTML = days;
};

document.querySelector(".prev").addEventListener("click", () => {
  date.setMonth(date.getMonth() - 1);
  renderCalendar();
});

document.querySelector(".next").addEventListener("click", () => {
  date.setMonth(date.getMonth() + 1);
  renderCalendar();
});

renderCalendar();

const dateEls = Array.from(document.querySelectorAll('.day'));
dateEls.forEach((dateEl) => {
    dateEl.addEventListener('click', (event) => {
        console.log(event.currentTarget.dataset.date);
    });
});
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Quicksand", sans-serif;
  }
  
  html {
    font-size: 62.5%;
  }
  
  .leaves {
    width: 100%;
    /* height: 100vh; */
    background-color: #12121f;
    color: #eee;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  
  .container {
    width: 100%;
    height: 100vh;
    background-color: #12121f;
    color: #eee;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  
  .calendar {
    width: 45rem;
    height: 52rem;
    background-color: #222227;
    box-shadow: 0 0.5rem 3rem rgba(0, 0, 0, 0.4);
  }
  
  .month {
    width: 100%;
    height: 12rem;
    background-color: #167e56;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 2rem;
    text-align: center;
    text-shadow: 0 0.3rem 0.5rem rgba(0, 0, 0, 0.5);
  }
  
  .month i {
    font-size: 2.5rem;
    cursor: pointer;
  }
  
  .month h1 {
    font-size: 3rem;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.2rem;
    margin-bottom: 1rem;
  }
  
  .month p {
    font-size: 1.6rem;
  }
  
  .weekdays {
    width: 100%;
    height: 5rem;
    padding: 0 0.4rem;
    display: flex;
    align-items: center;
  }
  
  .weekdays div {
    font-size: 1.5rem;
    font-weight: 400;
    letter-spacing: 0.1rem;
    width: calc(44.2rem / 7);
    display: flex;
    justify-content: center;
    align-items: center;
    text-shadow: 0 0.3rem 0.5rem rgba(0, 0, 0, 0.5);
  }
  
  .days {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    padding: 0.2rem;
  }
  
  .days div {
    font-size: 1.4rem;
    margin: 0.3rem;
    width: calc(40.2rem / 7);
    height: 5rem;
    display: flex;
    justify-content: center;
    align-items: center;
    text-shadow: 0 0.3rem 0.5rem rgba(0, 0, 0, 0.5);
    transition: background-color 0.2s;
  }
  
  .days div:hover:not(.today) {
    background-color: #262626;
    border: 0.2rem solid #777;
    cursor: pointer;
  }
  
  .prev-date,
  .fcc-other-month { 
    visibility:hidden;
 }
  .next-date {
    opacity: 0.5;
  }
  
  .green {
    background-color: #167e56;
  }

  .red {
    background-color: red;
  }
<div class="leaves">
      <div class="calendar">
        <div class="month">
          <i class="fas fa-angle-left prev"></i>
          <div class="date">
            <h1></h1>
            <p></p>
          </div>
          <i class="fas fa-angle-right next"></i>
        </div>
        <div class="weekdays">
          <div>Sun</div>
          <div>Mon</div>
          <div>Tue</div>
          <div>Wed</div>
          <div>Thu</div>
          <div>Fri</div>
          <div>Sat</div>
        </div>
        <div class="days"></div>
      </div>
    </div>

建议:在循环运行之前,您还可以将 .getDate().getMonth()值存储在变量中以提高性能。

编辑:以上部分回答了onclick. 对于年份问题,除了日期和月份之外,您还需要比较年份。

编辑 2:要在 DOM 中显示它,请添加一个类似的元素:<span id="selected-date"></span>,并在 click 事件侦听器中添加: document.getElementById('selected-date').innerText = event.currentTarget.dataset.date;


推荐阅读