const $showCalender = document.querySelector('#todo_calender');
const $yearMonth = document.querySelector('.year-month');
const $paintDates = document.querySelector('.dates');
const $goPrevBtn = document.querySelector('.go-prev');
const $goNextBtn = document.querySelector('.go-next');
const $goTodayBtn = document.querySelector('.go-today');
const $calenderBtn = document.getElementById('calender');
//goToday함수 부분에서 date값을 재할당 해줘야 하기 때문에 const에서 let으로 변경
let date = new Date();
let first = new Date(date.getFullYear(), date.getMonth(), 1);
console.log(first.getDay());
//재사용 해주기 위해 이전에 만들었던 코드를 함수로 만들어준다.
function renderCalender() {
const viewYear = date.getFullYear();//현재 년도
const viewMonth = date.getMonth();//이번 달(달은 0 ~ 11로 표현된다)
//연도와 월을 넣어줌
$yearMonth.textContent = `${viewYear}.${viewMonth + 1}`;
//지난 달 마지막 날짜와 요일
const prevLast = new Date(viewYear, viewMonth, 0);
const thisLast = new Date(viewYear, viewMonth + 1, 0);
const PLDate = prevLast.getDate();//지난 달 마지막 날짜
const PLDay = prevLast.getDay();//지난 달 마지막 요일
//이번 달 마지막 날짜와 요일
const TLDate = thisLast.getDate();//이번 달 마지막 날짜
const TLDay = thisLast.getDay();//이번 달 마지막 요일
//날짜를 담아둘 배열을 생성
const prevDates = [];//지난 달 날짜와 다음 달 날짜는 상황에 따라 그릴 수도, 그리지 않을 수도 있기 때문에 초기값은 빈 배열로 둠
const thisDates = [...Array(TLDate + 1).keys()].slice(1);
const nextDates = [];
//prevDates와 nextDates를 채워주는 로직
if(PLDay !== 6){
for(let i = 0;i < PLDay + 1;i++){
prevDates.unshift(PLDate - i);
}
}
//다음 달을 표현할 날짜들(이번 달 마지막 날짜의 요일을 기주능로 필요한 개수를 파악해서 1부터 1씩 증가시키며 nextDates 배열에 하나씩 채워 넣는 방식)
for(let i = 1;i < 7 - TLDay;i++){
nextDates.push(i);
}
//위에 3개의 배열을 html에 그림
const dates = prevDates.concat(thisDates, nextDates);//concat을 통해 3배열을 합친다.
//forEach메서드로 전체 요소들을 돌면서, html 코드로 데이터를 하나씩 수정해준다.
const firstDateIndex = dates.indexOf(1);//이번달의 첫번째 인덱스
const lastDateIndex = dates.lastIndexOf(TLDate);//이번달의 마지막 인덱스
console.log(firstDateIndex, lastDateIndex);
//이번달의 첫번째 인덱스보다 크고 마지막날의 인덱스보다 작으면 this클래스가 부여 둘다 해당하지 않으면 other클래스를 부여해주고
//other 클래스는 css에서 투명하게 꾸며준다 그러면 이번달에 해당하는 부분만 진하게 보인다.
dates.forEach((date, i) => {
const condition = i > firstDateIndex - 1 && i < lastDateIndex + 1
? 'this'
: 'other'
dates[i] = `<div class="date"><span class="${condition}">${date}</span></div>`;
});
$paintDates.innerHTML = dates.join('');//dates 배열에 join 메서드를 통해 문자열로 변형하여 html에 그려준다
//오늘 날짜 그리기
const today = new Date();
if(viewMonth === today.getMonth() && viewYear === today.getFullYear()) {
for(let date of document.querySelectorAll('.this')){
if(+date.innerText === today.getDate()) {
date.classList.add('today', 'active');
break;
}
}
}
change();
}
//달력을 클릭해서 해당 날짜에 하이라이트를 부여
//this클래스에만 적용
function changeActive(event){
event.stopPropagation();//상위 요소에 이벤트 전달을 막아준다.
for(let day of document.querySelectorAll('.this')){
if(day.classList.contains('active')){
day.classList.remove('active');
}
}
clickedDate1 = event.target;
clickedDate1.classList.add('active');
$toDoForm.addEventListener('submit', handleToDoSubmit);
}
//this클래스에 이벤트를 하나씩 넣어줌
function change(){
for(let i of document.querySelectorAll('.this')){
i.addEventListener('click', changeActive);
}
}
function prevMonth() {
date.setDate(1);
date.setMonth(date.getMonth() - 1);
renderCalender();
change();
}
function goToday(){
date = new Date();
renderCalender();
change();
}
function nextMonth() {
date.setDate(1);
date.setMonth(date.getMonth() + 1);
renderCalender();
change();
}
renderCalender();
$goNextBtn.addEventListener('click', nextMonth);
$goTodayBtn.addEventListener('click', goToday);
$goPrevBtn.addEventListener('click', prevMonth);
$calenderBtn.addEventListener('click', () => {
$showCalender.classList.toggle('hidden');
})
이렇게 달력을 구현해 봤는데 혹시 여기에서 칸마다 todo-list를 구현하고 싶은데 고민을 해보고 이것저것 시도도 해봤는데 너무 어렵네요… 혹시 어떻게 해야될 지 알려주시면 정말 감사하겠습니다.