Everything has an expiration date
★★★Javascript 20231204 [프로그램소스 만년달력!!] - Test025, Test025_MyTest 본문
[Javascript]/Program source (Javascript)
★★★Javascript 20231204 [프로그램소스 만년달력!!] - Test025, Test025_MyTest
Jelly-fish 2023. 12. 4. 01:32
WebApp03
Test025.html

(이것은 나의 첫 풀이이다... 년/월을 변경하고 버튼을 누르면 테이블의 행(tr)이 밑에 계속계속 append 된다. 화가 난다.)
Test025.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test025.html</title>
<style type="text/css">
* {color: #223322; font-family: 나눔고딕코딩; font-weight: bold;}
input:focus {background-color: #eeeedd;}
input.btn {font-weight: bold; font-family: 맑은 고딕;}
input.btn:hover {color: orange; background-color: #334433;}
input.btn:active {color: red;}
textarea {font-family: 나눔고딕코딩; font-weight: bold; margin: 2px;}
#txtCount {width: 20px; text-align: right;}
.btn {width: 200px;}
.txt {width: 67px; text-align: center; font-weight: bold;}
td {text-align: right; background-color: #ffeeff;}
th {width: 40px;}
</style>
<script type="text/javascript">
// 1단계. 1년 1월 1일 부터... 입력 년도 기준 전년도 12월 31일 까지의 총 날짜 수 구하기
// 2단계. 해당년도의 1월 1일 부터... 해당 년도 해당 월 1일 까지의 총 날짜 수 구해서 1단계에 더하기
// 3단계. 해당 년도 해당 월의 첫 날(1일)의 요일 구하기
// 4단계. 해당 년도 해당 월의 마지막 날짜 구하기 (28일 or 29일 or 30일 or 31일)
// 5단계. 해당 년도 해당 월 기준 달력 구성(출력, 그리기)
// 해당 월의 1일이 시작되기 전에 빈 칸 td 채우기
// 1년 1월 1일은 월요일이다.
// 연수가 4로 나누어 떨어지면서 100으로 나누어 떨어지지 않는 해는 윤년.
// 연수가 400으로 나누어 떨어지는 해는 윤년.
// 2000년 1월
function createCalendar()
{
var dayOfWeekArr = ["일", "월", "화", "수", "목", "금", "토"];
var resultDayOfWeek;
var monthDaysArr = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var totYearDays = 0;
var totMonthDays = 0;
var allDays = 0;
var inYear = Number(document.getElementById("txtYear").value);
var inMonth = Number(document.getElementById("txtMonth").value);
var lastDay;
// (1) 총 연도 일수를 구한다.
for (var i = 1; i < inYear; i++)
{
// 윤년 조건
if ( (i % 4 == 0)&&(i % 100 != 0) || (i % 400 == 0) )
{
totYearDays += 366;
}
// 평년
else
{
totYearDays += 365;
}
}
// (2) 총 월 일수를 구한다.
for (var i = 0; i < (inMonth - 1); i++)
{
// ⓐ 입력한 해가 윤년이면, 2월의 끝일은 29일로 설정 후 더하기
if ( (inYear % 4 == 0)&&(inYear % 100 != 0) || (inYear % 400 == 0) )
{
monthDaysArr[1] = 29;
}
else
{
monthDaysArr[1] = 28;
}
// ⓑ 평년이면 그대로 더하기.
totMonthDays += monthDaysArr[i];
}
//alert("연도 일수 : " + totYearDays + ", 월 일수 : " + totMonthDays);
// 올해의 1일 날짜를 구해야 하므로 + 1을 해 주어야 한다.
allDays = totYearDays + totMonthDays + 1;
//alert("연 일수 : " + totYearDays);
// 연 일수 : 738520
//alert("월 일수 : " + totMonthDays);
// 월 일수 : 273
// (사용자가 입력한 달의 1일을 구해야 하므로 1을 더해주면...)
// ↓
// 월 일수 : 274
//alert("요일 : " + (allDays % 7));
// 요일 : 0
// (3) 총 일수를 7로 나눈 나머지 값으로 요일을 구한다.
// ===============
// 나머지 요일
// ===============
// 0 일
// 1 월
// 2 화
// 3 수
// 4 목
// 5 금
// 6 토
// ===============
resultDayOfWeek = allDays % 7;
// 요일 출력
//alert(resultDayOfWeek);
// (4) 입력한 월의 마지막 날짜를 구한다.
lastDay = monthDaysArr[(inMonth - 1)];
//alert(lastDay);
// (5) 테이블 엘리먼트(객체)에 접근하여 노드 담기 (테이블 오브젝트 가져오기)
var tableNode = document.getElementById("calendarTbl");
// (6) tr(table row) 노드 새롭게 생성하기
// [for문을 돌면서 숫자를 1부터 ~ lastDay(입력한 월의 마지막 날짜)까지 td에 담고 tr에 담기.]
var day = 1;
for (var i = 1; i <= 6; i++)
{
var trNode = document.createElement("tr");
// 첫 번째 줄이라면...
if (i == 1)
{
// 0부터 ~ 요일 수(resultDayOfWeek) 까지 공백을 td에 넣기
for (var j = 0; j < resultDayOfWeek; j++)
{
trNode.appendChild(createTdNode(" "));
}
// 요일 수(resultDayOfWeek)부터 ~ 6까지 i를 넣기
for (var k = resultDayOfWeek; k < 7; k++)
{
trNode.appendChild(createTdNode(day++));
}
// 한 행을 기록하기
tableNode.appendChild(trNode);
}
else
{
var trNode = document.createElement("tr");
// 총 7개의 Day(숫자 일수)를 td에 넣고, tr에 넣은 뒤 한 행 기록.
for (var j = 0; j < 7; j++)
{
if (day > lastDay)
break;
trNode.appendChild(createTdNode(day++));
}
tableNode.appendChild(trNode);
}
}
}
function createTdNode(val)
{
var textNode = document.createTextNode(val);
var tdNode = document.createElement("td");
tdNode.appendChild(textNode);
return tdNode;
}
</script>
</head>
<body>
<div>
<h1>테이블 동적 생성으로 만년달력 그리기</h1>
<hr>
</div>
<div>
<form>
<br>
<input type="text" id="txtYear" class="txt"> 년
<input type="text" id="txtMonth" class="txt"> 월
<br><br>
<input type="button" class="btn" value="만년달력 그리기" onclick="createCalendar()">
<br><br>
<table border="1" id="calendarTbl">
<tr>
<th>일</th>
<th>월</th>
<th>화</th>
<th>수</th>
<th>목</th>
<th>금</th>
<th>토</th>
</tr>
</table>
</form>
</div>
</body>
</html>
Test025_MyTest.html

그걸 고쳤다~! ㅎㅎ 선생님께 여쭤봤더니
div에 id만 부여한 후, 결과 버튼을 클릭해서 함수를 호출 할 때마다 테이블을 새롭게 생성해 보라고 조언해 주셨다!
그런데, 그렇게 해도 테이블이 계속 이어져서 나오는 문제가 있었는데...
테이블(<table>)이 div의 자식 노드가 되면서, 이전 소스인 Test025.html에서 테이블 행(<tr>)이 append 되던 것처럼
테이블이 이어져서 나왔다...
그래서 div의 자식 노드를 모두 삭제해 주기 위해 `innerHTML` 을 모두 비워주자(자식노드 태그제거) 이 문제점이 해결 되었다!
ⓐ 핵심 변경 사항 - 테이블 제거 후 <div id="calendarTbl"></div> 만 선언
<div id="calendarTbl">
</div>
ⓑ 핵심 변경 사항 - 버튼을 클릭 할 때마다, 테이블을 새롭게 생성. (document.createElement("table"))
// (1). 테이블 (table)노드 생성
var creTableNode = document.createElement("table");
// (2). 테이블 행(table row) 노드 생성
var creTrNode = document.createElement("tr");
// (3). 달력 형식 테이블 구성하기
var sunday = document.createTextNode("일");
var creThNode1 = document.createElement("th");
creThNode1.appendChild(sunday);
var monday = document.createTextNode("월");
var creThNode2 = document.createElement("th");
creThNode2.appendChild(monday);
var tuesday = document.createTextNode("화");
var creThNode3 = document.createElement("th");
creThNode3.appendChild(tuesday);
var wednesday = document.createTextNode("수");
var creThNode4 = document.createElement("th");
creThNode4.appendChild(wednesday);
var thursday = document.createTextNode("목");
var creThNode5 = document.createElement("th");
creThNode5.appendChild(thursday);
var friday = document.createTextNode("금");
var creThNode6 = document.createElement("th");
creThNode6.appendChild(friday);
var saturday = document.createTextNode("토");
var creThNode7 = document.createElement("th");
creThNode7.appendChild(saturday);
// (4). 테이블 행(table row)에 테이블 데이터 (table data) 모두 추가
creTrNode.appendChild(creThNode1);
creTrNode.appendChild(creThNode2);
creTrNode.appendChild(creThNode3);
creTrNode.appendChild(creThNode4);
creTrNode.appendChild(creThNode5);
creTrNode.appendChild(creThNode6);
creTrNode.appendChild(creThNode7);
// (5). 테이블 노드에 테이블 행 노드를 자식 계층으로 추가.
creTableNode.appendChild(creTrNode);
// (6-1). <div id="calendarTbl"></div> 객체를 가져온다.
// (6-2). 위에서 만든 달력 테이블을 자식 게층으로 추가한다.
document.getElementById("calendarTbl").appendChild(creTableNode);
// -------------------------------------- =========================
// (6-1) (6-2)
ⓒ 핵심 변경 사항 - innerHTML 제거
var parentObj = document.getElementById("calendarTbl");
// 버튼을 클릭해서 함수를 호출할 때마다
// 자식 노드에 해당하는 HTML 태그들을 전부 삭제해서
// 자식 노드를 모두 제거해 주었다.
parentObj.innerHTML = "";
Test025_MyTest.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test025_MyTest.html</title>
<style type="text/css">
* {color: #223322; font-family: 나눔고딕코딩; font-weight: bold;}
input:focus {background-color: #eeeedd;}
input.btn {font-weight: bold; font-family: 맑은 고딕;}
input.btn:hover {color: orange; background-color: #334433;}
input.btn:active {color: red;}
textarea {font-family: 나눔고딕코딩; font-weight: bold; margin: 2px;}
#txtCount {width: 20px; text-align: right;}
.btn {width: 200px;}
.txt {width: 67px; text-align: center; font-weight: bold;}
td {text-align: right; background-color: #ffeeff;}
th {width: 40px;}
</style>
<script type="text/javascript">
// 1단계. 1년 1월 1일 부터... 입력 년도 기준 전년도 12월 31일 까지의 총 날짜 수 구하기
// 2단계. 해당년도의 1월 1일 부터... 해당 년도 해당 월 1일 까지의 총 날짜 수 구해서 1단계에 더하기
// 3단계. 해당 년도 해당 월의 첫 날(1일)의 요일 구하기
// 4단계. 해당 년도 해당 월의 마지막 날짜 구하기 (28일 or 29일 or 30일 or 31일)
// 5단계. 해당 년도 해당 월 기준 달력 구성(출력, 그리기)
// 해당 월의 1일이 시작되기 전에 빈 칸 td 채우기
// 1년 1월 1일은 월요일이다.
// 연수가 4로 나누어 떨어지면서 100으로 나누어 떨어지지 않는 해는 윤년.
// 연수가 400으로 나누어 떨어지는 해는 윤년.
// 2000년 1월
var clickCnt = 0;
function createCalendar()
{
var parentObj = document.getElementById("calendarTbl");
// 버튼을 클릭해서 함수를 호출할 때마다
// 자식 노드에 해당하는 HTML 태그들을 전부 삭제해서
// 자식 노드를 모두 제거해 주었다.
parentObj.innerHTML = "";
var creTableNode = document.createElement("table");
//alert("두 번째 클릭입니다. 테이블을 삭제합니다..." + clickCnt);
//alert(document.getElementById("calendarTbl").getElementsByTagName("tbody"));
//alert(creTableNode);
//alert(document.getElementById("calendarTbl").innerHTML);
//document.getElementById("calendarTbl").remove();
//alert(document.querySelectorAll("table"));
/* var divEle = document.getElementById("calendarTbl");
var removeE = divEle.querySelectorAll("table");
removeE.parentNode.removeChild(removeE); */
//alert(document.getElementById("calendarTbl").children);
var creTrNode = document.createElement("tr");
var sunday = document.createTextNode("일");
var creThNode1 = document.createElement("th");
creThNode1.appendChild(sunday);
var monday = document.createTextNode("월");
var creThNode2 = document.createElement("th");
creThNode2.appendChild(monday);
var tuesday = document.createTextNode("화");
var creThNode3 = document.createElement("th");
creThNode3.appendChild(tuesday);
var wednesday = document.createTextNode("수");
var creThNode4 = document.createElement("th");
creThNode4.appendChild(wednesday);
var thursday = document.createTextNode("목");
var creThNode5 = document.createElement("th");
creThNode5.appendChild(thursday);
var friday = document.createTextNode("금");
var creThNode6 = document.createElement("th");
creThNode6.appendChild(friday);
var saturday = document.createTextNode("토");
var creThNode7 = document.createElement("th");
creThNode7.appendChild(saturday);
creTrNode.appendChild(creThNode1);
creTrNode.appendChild(creThNode2);
creTrNode.appendChild(creThNode3);
creTrNode.appendChild(creThNode4);
creTrNode.appendChild(creThNode5);
creTrNode.appendChild(creThNode6);
creTrNode.appendChild(creThNode7);
creTableNode.appendChild(creTrNode);
document.getElementById("calendarTbl").appendChild(creTableNode);
var dayOfWeekArr = ["일", "월", "화", "수", "목", "금", "토"];
var resultDayOfWeek;
var monthDaysArr = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var totYearDays = 0;
var totMonthDays = 0;
var allDays = 0;
var inYear = Number(document.getElementById("txtYear").value);
var inMonth = Number(document.getElementById("txtMonth").value);
var lastDay;
// (1) 총 연도 일수를 구한다.
for (var i = 1; i < inYear; i++)
{
// 윤년 조건
if ( (i % 4 == 0)&&(i % 100 != 0) || (i % 400 == 0) )
{
totYearDays += 366;
}
// 평년
else
{
totYearDays += 365;
}
}
// (2) 총 월 일수를 구한다.
for (var i = 0; i < (inMonth - 1); i++)
{
// ⓐ 입력한 해가 윤년이면, 2월의 끝일은 29일로 설정 후 더하기
if ( (inYear % 4 == 0)&&(inYear % 100 != 0) || (inYear % 400 == 0) )
{
monthDaysArr[1] = 29;
}
else
{
monthDaysArr[1] = 28;
}
// ⓑ 평년이면 그대로 더하기.
totMonthDays += monthDaysArr[i];
}
//alert("연도 일수 : " + totYearDays + ", 월 일수 : " + totMonthDays);
alert("연 일수 : " + totYearDays);
// 연 일수 : 738520
alert("월 일수 : " + totMonthDays);
// 월 일수 : 273
// 사용자가 입력한 달의 1일 날짜를 구해야 하므로 + 1
allDays = totYearDays + totMonthDays + 1;
// (3) 총 일수를 7로 나눈 나머지 값으로 요일을 구한다.
// ===============
// 나머지 요일
// ===============
// 0 일
// 1 월
// 2 화
// 3 수
// 4 목
// 5 금
// 6 토
// ===============
resultDayOfWeek = allDays % 7;
// 요일 출력
//alert(resultDayOfWeek);
// (4) 입력한 월의 마지막 날짜를 구한다.
lastDay = monthDaysArr[(inMonth - 1)];
//alert(lastDay);
// (5) 테이블 엘리먼트(객체)에 접근하여 노드 담기 (테이블 오브젝트 가져오기)
//var tableNode = document.getElementById("calendarTbl");
// (6) tr(table row) 노드 새롭게 생성하기
// [for문을 돌면서 숫자를 1부터 ~ lastDay(입력한 월의 마지막 날짜)까지 td에 담고 tr에 담기.]
var day = 1;
for (var i = 1; i <= 6; i++)
{
var trNode = document.createElement("tr");
// 첫 번째 줄이라면...
if (i == 1)
{
// 0부터 ~ 요일 수(resultDayOfWeek) 까지 공백을 td에 넣기
for (var j = 0; j < resultDayOfWeek; j++)
{
trNode.appendChild(createTdNode(" "));
}
// 요일 수(resultDayOfWeek)부터 ~ 6까지 i를 넣기
for (var k = resultDayOfWeek; k < 7; k++)
{
trNode.appendChild(createTdNode(day++));
}
// 한 행을 기록하기
//tableNode.appendChild(trNode);
creTableNode.appendChild(trNode);
}
else
{
var trNode = document.createElement("tr");
// 총 7개의 Day(숫자 일수)를 td에 넣고, tr에 넣은 뒤 한 행 기록.
for (var j = 0; j < 7; j++)
{
if (day > lastDay)
break;
trNode.appendChild(createTdNode(day++));
}
//tableNode.appendChild(trNode);
creTableNode.appendChild(trNode);
}
}
}
function createTdNode(val)
{
var textNode = document.createTextNode(val);
var tdNode = document.createElement("td");
tdNode.appendChild(textNode);
return tdNode;
}
</script>
</head>
<body>
<div>
<h1>테이블 동적 생성으로 만년달력 그리기</h1>
<hr>
</div>
<div>
<form>
<br>
<input type="text" id="txtYear" class="txt"> 년
<input type="text" id="txtMonth" class="txt"> 월
<br><br>
<input type="button" class="btn" value="만년달력 그리기" onclick="createCalendar()">
<br><br>
<div id="calendarTbl">
</div>
<!-- <table border="1" id="calendarTbl">
<tr>
<th>일</th>
<th>월</th>
<th>화</th>
<th>수</th>
<th>목</th>
<th>금</th>
<th>토</th>
</tr>
</table> -->
</form>
</div>
</body>
</html>