[미니프로젝트] Calendar

Changyun Go·2021년 12월 10일
2
post-thumbnail

GitHub

요구사항


  1. 오늘의 현재 요일 표기
  2. 오늘의 현재 날짜 표기
  3. 오늘의 현재 월 표기
  4. 오늘의 현재 연도 표기
  5. 일,월,화,수,목,금,토 요일 라벨링 표기
  6. 현재 월의 1일이 무슨 요일인지 판별하고, 해당 요일 라벨링에 1일 표기하기
  7. 현재 월의 마지막 날짜까지 달력에 표기하기
  8. 우측 화살표를 클릭 했을때, 다음 달의 요일 및 날짜 표기
  9. 좌측 화살표를 클릭 했을때, 이전 달의 요일 및 날짜 표기
  10. 특정 날짜를 클릭 했을때, 상단의 요일 및 날짜 반영하기

실행 화면


Code


HTML

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<link rel="stylesheet" type="text/css" href="style.css">
		<script src="script.js" type="text/javascript" defer></script>
		<title>Calendar</title>
	</head>
	<body>
		<div class="container">
			<div class="item" id="today">
				<div id="week"></div>
				<div id="date"></div>
			</div>
		<div class="item">
			<button type="button" onclick="prev()"><&emsp;&emsp;&emsp;&emsp;&nbsp;&nbsp;</button>
			<div id="year" class="top-bar"></div>
			<div id="month" class="top-bar"></div>
			<button type="button" onclick="next()">&emsp;&emsp;&emsp;&emsp;&nbsp;&nbsp;></button><br>
			<table>
				<tr>
					<th></th>
					<th></th>
					<th></th>
					<th></th>
					<th></th>
					<th></th>
					<th></th>
				</tr>
				<tr>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
				</tr>
				<tr>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
				</tr>
				<tr>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
				</tr>
				<tr>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
				</tr>
				<tr>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
				</tr>
				<tr>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
					<td></td>
				</tr>
			</table>
		</div>
    </body>
</html>
      

CSS

body{
    margin: 0;
}
button {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    border: 0;
    outline: 0;
    background-color: white;
    font-size: 20px;
    margin-bottom: 10px;
  }
th{
    font-size: 17px;
}
td{
    width: 50px;
    height: 50px;
    font-size: 20px;
}
.container{
    display: flex;
    align-items:center;
    justify-content: center;
    height: 100vh;
}
.item{
    text-align: center;
    font-size: 18px;
}
#today{
    width: 160px;
    margin-right: 60px;
    margin-bottom: 60px;
    font-weight: bold;
}
#week{
    font-size: 30px;
}
#date{
    font-size: 70px;
}
.top-bar{
    display: inline;
    font-weight: bold;
}
.today-circle{
    width: 43px;
    height: 43px;
    border-radius: 50%;
    border-width: 3px;
    background-color: purple;
    color: white;
}
.click-circle{
    width: 43px;
    height: 43px;
    border-radius: 50%;
    border-width: 2px;
    border-style: solid;
    border-color: purple;
}

JavaScript

const days = ["일", "월", "화", "수", "목", "금", "토"];
const months = ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"];
let newDate = new Date();
let year = newDate.getFullYear();
let month = newDate.getMonth();
let day = newDate.getDay();
let week = days[day];
let date = newDate.getDate();
let selectYear = document.querySelector("#year")
let selectMonth = document.querySelector("#month")
let selectWeek = document.querySelector("#week")
let selectDate = document.querySelector("#date")
let table = document.querySelector("table");
let td = document.querySelector("td");
let dateNum = 0;
let firstDay = 0;
let lastDate = 0;
let lastDay = 0;
let clickDay = 0;
let today = 0;
let preTarget = 0;
let preTargetText = 0;

function clickDate(){
    if(event.target.nodeName == "TD" && event.target.textContent !== ""){
        if(preTarget !== 0 && (preTargetText != date || month != newDate.getMonth())){
            preTarget.className = "";
        }
        if(event.target.textContent != date || newDate.getMonth() != month){
            event.target.className = "click-circle";
        }
        selectDate.textContent = event.target.textContent + "일";
        clickDay = firstDay + event.target.textContent % 7 - 1;

        if(clickDay < 0){
            clickDay = clickDay + 7;
        }
        else if(clickDay > 6){
            clickDay = clickDay - 7;
        }
        selectWeek.textContent = days[clickDay] + "요일";
        preTarget = event.target;
        preTargetText = event.target.textContent;
    }
}

function dateMaker(){
    if(firstDay < 0){
        firstDay = firstDay + 7;
    }
    else if(firstDay > 6){
        firstDay = firstDay - 7;
    }
    for(let i = 0; i < firstDay; i++){
        table.rows[1].cells[i].textContent = null;
    }
    for(let i = firstDay; i <= 6; i++){
        dateNum++;
        table.rows[1].cells[i].textContent = dateNum;
    }
    for(let i = 2; i <= 4; i++){
        for(let j = 0; j <= 6; j++){
            dateNum++;
            table.rows[i].cells[j].textContent = dateNum;
        }
    }
    lastDay = firstDay + (lastDate - 29);

    if(lastDay > 6){
        lastDay = lastDay - 7;

        for(let i = 0; i <= 6; i++){
            dateNum++;
            table.rows[5].cells[i].textContent = dateNum;
        }
        for(let i = 0; i <= lastDay; i++){
            dateNum++;
            table.rows[6].cells[i].textContent = dateNum;
        }
        for(let i = lastDay + 1; i <= 6; i++){
            table.rows[6].cells[i].textContent = null;
        }
    }
    else{
        for(let i = 0; i <= lastDay; i++){
            dateNum++;
            table.rows[5].cells[i].textContent = dateNum;
        }
        for(let i = lastDay + 1; i <= 6; i++){
            dateNum++;
            table.rows[5].cells[i].textContent = null;
        }
        for(let i = 0; i <= 6; i++){
            table.rows[6].cells[i].textContent = null;
        }
    }
    if(month === newDate.getMonth() && year === newDate.getFullYear()){
        today = table.rows[Math.ceil((date + firstDay) / 7)].cells[day];
        today.className = "today-circle";
    }
    else{
        today.className = "";
    }
    preTarget.className = "";
}
function lastDateCheck(){
    if(month === 3||month === 5||month === 8||month === 10){
        lastDate = 30;
    }
    else if(month === 1){
        if(year % 4 === 0){
            lastDate = 29;
        }
        else{
            lastDate = 28;
        }
    }
    else{
        lastDate = 31;
    }
}
function firstDayDisplay(){
    if(month !== newDate.getMonth() || year !== newDate.getFullYear()){
        selectWeek.textContent = days[firstDay] + "요일";
        selectDate.textContent = 1 + "일";
    }
    else{
        selectWeek.textContent = week + "요일";
        selectDate.textContent = date + "일";
    }
}

function prev(){
    if(month === 0){
        month = 11;
        year--;
    }
    else{
        month--;
    }
    selectMonth.textContent = months[month];
    selectYear.textContent = year + "년";

    lastDateCheck()
    dateNum = 0;
    lastDay = firstDay - 1;
    firstDay = firstDay - (lastDate - 28);

    dateMaker();
    firstDayDisplay();
}
function next(){
    if(month === 11){
        month = 0;
        year++;
    }
    else{
        month++;
    }
    selectMonth.textContent = months[month];
    selectYear.textContent = year + "년";

    lastDateCheck()
    dateNum = 0;
    firstDay = lastDay + 1;

    dateMaker();
    firstDayDisplay();
}
selectYear.textContent = year + "년";
selectMonth.textContent = months[month];
selectWeek.textContent = week + "요일";
selectDate.textContent = date + "일";
firstDay = newDate.getDay() - date % 7 + 1;

lastDateCheck()
dateMaker();

table.onclick = clickDate;

P.S.

✍️ for문을 너무 남용한 게 아닌가 싶긴 하지만😅 만들면서 새로운 것들을 많이 알게 돼서 꽤 만족스러운 작업이었다😁

사실 중간에 오랜 시간 막혔던 부분이 있었는데, 마음먹고 코드를 싹 지우고 칠판에 그려가면서 차근차근 써 내려갔더니 2시간도 안 돼서 해결했다..😂 다음부터는 고집부리지 말아야겠다😏

끝난 줄 알고 이리저리 만지작거리다 보면 계속 버그를 찾을 수 있었다. 만드는 것만큼이나 테스트하는 것도 참 중요하다는 걸 느꼈다.

Reference


0개의 댓글