✅ 시계 구현하기
function fnFillZero(n){ // 3
return n < 10 ? '0'+n : n; // 03월 표시
}
// setInterval(함수,밀리초) : 밀리초마다 함수 실행
setInterval(function(){
let now = new Date(); // 현재 일시
document.querySelector("#year").textContent = now.getFullYear();
document.querySelector("#month").textContent = fnFillZero(now.getMonth()+1); //03
document.querySelector("#day").textContent = fnFillZero(now.getDate()); // 21
document.querySelector("#hour").textContent = fnFillZero(now.getHours()); // 09
document.querySelector("#minute").textContent = fnFillZero(now.getMinutes());
document.querySelector("#second").textContent = fnFillZero(now.getSeconds());
if(now.getSeconds() >= 50){
// .className = "class 속성값" <h1 id="counter" class="over50second">
document.querySelector("#counter").className = 'over50second';
// setAttribute : 속성 등록 함수
// setAttribute("속성명",'속성값') <h1 id="counter" class="over50second">
// document.querySelector("#counter").setAttribute("class",'over50second');
} else{
// .className = "" 등록된 class 속성의 값을제거 <h1 id="counter" class="">
document.querySelector("#counter").className= '';
// removeAttribute("속성명") : 속성명 제거
// document.querySelector("#counter").removeAttribute("class");
}
},1000);
✅ .className = "속성값"
등록된 class 추가
<h1 id="counter" class="over50second">
✅ .className = ""
등록된 class 제거
<h1 id="counter" class="">
✅ setAttribute
setAttribute("속성명",'속성값') <h1 id="counter" class="over50second">
document.querySelector("#counter").setAttribute("class",'over50second');
✅ removeAttribute("속성명") 속성값 제거
document.querySelector("#counter").removeAttribute("class");
☑️ timer
✅ setTimeout
한번만 동작하는 타이머 함수
let id = setTimeout(함수,밀리초)
let timerid = setTimeout(function (){
console.log("5초 후 출력");
},5000)
✅ setInterval
반복해서 동작하는 타이머 함수
let id = setInterval(함수,밀리초): 밀리초마다 함수를 실행
clearInterval(id) : setInterval로 설정된 함수 중지.
let n = 0;
timerid = setInterval(function (){
console.log(n++);
},1000)
setTimeout(function (){
clearInterval(timerid);
console.log(timerid + "중지됨");
},5000);
☑️ 이벤트(Event)
특정 요소객체의 이벤트 속성에 접근 후 이벤트 핸들러 연결 방식
const area1 = document.querySelector("#area1");
// 이벤트 핸들러 : 이벤트가 발생시 호출되는 함수
document.querySelector("#btn1").onclick = function(){
area1.innerHTML += "btn1 버튼이 클릭되었습니다.<br/>"
}
document.querySelector("#btn2").onclick = function(){
area1.innerHTML += "btn2 버튼이 클릭되어 btn1이벤트 제거함.<br/>"
document.querySelector("#btn1").onclick = null; // 이벤트 핸들러 제거
}
✅ 인라인 방식 이벤트
요소내부에 직접 이벤트 속성제시하여 핸들러 정의 방식
<button onclick="document.querySelector('#area2').innerHTML+= '첫번째 버튼 클릭<br/>'">실행확인1</button>
<button onclick="test1()" >실행확인2</button>
<div id="area2" class="area"></div>
<script>
function test1(){
document.querySelector("#area2").innerHTML += '두번째 버튼 클릭<br/>';
}
</script>
✅ 표준 이벤트 모델(addEventListener)
w3c에서 공식적으로 지정한 이벤트 모델
<button id="btn3">실행확인</button>
<script>
const btn3 = document.querySelector("#btn3");
btn3.addEventListener("click", function(){
alert("표준 이벤트 모델 테스트");
})
btn3.addEventListener("mouseenter",function(){
btn3.style.backgroundColor = "red";
})
btn3.addEventListener("mouseout",function(){
btn3.style.backgroundColor = null;
})
</script>
✅ 이벤트가 발생한 요소에 접근하는 방법
1) 고전이벤트방식
<button id="btn4">고전이벤트방식</button>
<script>
document.querySelector("#btn4").onclick = function(e){
// e : 이벤트객체. 이벤트 정보를 저장하고 있는 객체
console.log("e:",e);
console.log("e.target",e.target); // 이벤트 발생된 요소 객체
console.log("window.event",window.event);
console.log("window.event.target",window.event.target); //이벤트 발생된 요소 객체
console.log("this",this) // 이벤트 발생된 요소 객체
e.target.innerHTML = "버튼 클릭됨";
window.event.target.style.backgroundColor = "red";
this.style.color="white";
}
</script>
2) 표준이벤트방식
<button id="btn5">표준이벤트방식</button>
<script>
document.querySelector("#btn5").addEventListener("click",function(e){
console.log("e.target",e.target); // 이벤트 발생된 요소 객체
console.log("window.event.target",window.event.target); //이벤트 발생된 요소 객체
console.log("this",this);// 이벤트 발생된 요소 객체
})
</script>
3) 인라인이벤트방식(1)
<button onclick="test2();">인라인 이벤트방식1</button>
<script>
function test2(){ // 이벤트 핸들러 기능. 함수
console.log("window.event.target",window.event.target);
window.event.target.innerHTML = "버튼변경";
console.log("this",this); // window 객체.
}
</script>
4) 인라인이벤트방식(2)
<button onclick="test3(this);">인라인 이벤트방식2</button>
<script>
function test3(btn){
btn.innerHTML = "버튼내용변경2";
btn.style.backgroundColor = "red";
}
</script>
✅ button 태그의 내용으로 클릭한 경우 배경색을 변경 함수를 구현하기
<button onclick="changeBackground()">red</button>
<button onclick="changeBackground()">blue</button>
<button onclick="changeBackground()">green</button>
<button onclick="changeBackground()">pink</button>
<script>
function changeBackground(){
window.event.target.style.backgroundColor = window.event.target.innerHTML;
}
</script>
✅ button 태그를 클릭한 버튼1의 배경색을 빨강, 버튼2의 배경색은 파란, 버튼3의 배경색은 초록으로 변경하는 함수를 구현하기
<button onclick="changeBackground2()">버튼1</button>
<button onclick="changeBackground2()">버튼2</button>
<button onclick="changeBackground2()">버튼3</button>
<script>
function changeBackground2(){
const btn = window.event.target;
if(btn.innerHTML == "버튼1"){
btn.style.backgroundColor = "red";
} else if(btn.innerHTML == "버튼2"){
btn.style.backgroundColor = "blue";
} else{
btn.style.backgroundColor = "green";
}
}
</script>
✅ option의 value 값에 맞는 이미지 표출
<form name="f">
<table>
<tr>
<td>
<select name="s" onchange="drawimg()">
<option value="strawberry.gif">딸기</option>
<option value="banana.jpg">바나나</option>
<option value="apple.gif">사과</option>
</select>
</td>
<td>
<img name="img2" src="images_01/strawberry.gif" width="100" height="120">
</td>
</tr>
</table>
</form>
<script>
function drawimg(){
let img = document.getElementsByName("img2")[0];
img.src = "images_01/" + document.getElementsByName("s")[0].value;
/*
BOM : Browser Object Model 계층도 이용
let img = document.img2;
img.src = "images_01/" + document.f.s.value;
*/
}
</script>

☑️ Key 이벤트
✅ keydown | keypress : 키가 눌려질때 발생 이벤트
- keydown : 키보드에서 키가 눌려질때 발생됨. 모든키
- keypress : 키보드에서 키가 눌려있는 상태. function키, 기능키 등에서는 발생 안됨
✅ keyup : 키가 올라올때 발생되는 이벤트
document.getElementById("userName").onkeyup = function(e){
console.log(e); // key 이벤트.
console.log(this.value); // input 태그의 value
console.log(e.key); // 눌려진 키의 키값
console.log(e.keyCode); // 눌려진 키의 코드 값. enter : 13
}
✅태그별 기본적으로 가지고 있는 이벤트 제거
- a 태그 : 클릭시 href 속성에 쓰여져 있는 url을 요청하는 기본 이벤트 존재
- form 태그의 submit 버튼 : form 태그의 action 속성에 쓰여져있는 url로 입력값들과 함께 요청하는 기본 이벤트 존재
- 태그 내에 기본설정된 이벤트를 실행을 막을때는 return false 로 설정함
<a href="https://www.naver.com" onclick="alert('네이버 연결 못함');return false">네이버로 이동하기</a><
<a href="https://www.gogle.com" onclick="return test4();">구글로 이동하기</a><br/>
<script>
function test4(){
/*
if(confirm("구글 페이지로 이동하시겠습니까?")){
return true;
} else{
return false;
}
*/
return confirm("구글 페이지로 이동하시겠습니까?");
}
</script>
✅ 간단한 ID 유효성 검사
아이디의 유효성 검사 : 영문자 또는 숫자로만 5글자 이상 12글자 이하 가능
형식에 맞지 않은 경우 => 알림창 출력. 기본이벤트 막기
형식에 맞는 경우 => 기본이벤트 실행
<form action="ex11_exam.html" method="get">
아이디 : <input type="text" id="userId" name="userId" required><br/>
비밀번호 : <input type="password" id="userPw" name="userPw" required><br/>
<input type="submit" onclick="return valiadte();" >
</form>
<script>
const userId = document.querySelector("#userId").value;
if(userId.length >= 5 && userId.length <=12){ // 아이디길이 만족
for(let i=0; i<userId.length; i++){
if(userId.charAt(i) > 0 && userId.charAt(i) <= 9 // 숫자,영문자 가능
|| userId.charAt(i) >= 'A' && userId.charAt(i) <= 'Z' // 대문자
|| userId.charAt(i) >= 'a' && userId.charAt(i) <= 'z'){ // 소문자
} else { // 숫자,영문자 아닌 경우
alert("숫자 또는 영문자만 가능합니다.");
return false;
}
}
} else{ // 아이디 길이 오류
alert("아이디는 5자이상, 12 이하만 가능합니다.");
return false;
}
</script>
✅ 정규식을 이용하여 아이디 유효성 검사하기
/메타문자/
[a-z0-9] : 소문자,숫자
{m,n} : m개 이상 n개 이하
^ : 시작문자
$ : 종료문자
i : 대소문자 구분없이
const regExp = /^[a-z0-9]{5,12}$/i;
// .test : 정규표현식과 일치.
if(!regExp.test(userId)){
alert("유효한 아이디의 형식이 아닙니다. 다시 입력해주세요!");
// .select : 내용들을 선택
document.getElementById("userId").select();
return false; // submit 기본 이벤트 취소
}
☑️ 배열
변수 선언시 별도의 자료형을 지정하지 않으므로 어떤 자료형이든 하나의 배열에 저장할 수 있음
크기에 제한 없음. 자바의 ArrayList와 비슷, [] 표기법을 사용
function arrayTest1(){
const arr = ['홍길동',20,'서울',true,[1,2,3]]; // 배열의 선언. 초기화
console.log(arr); // 배열객체 전부
console.log(arr[2]); // 3번째 객체
console.log(arr[4]); // 5번째 객체
console.log(arr[4][1]); // 5번째 객체의 2번째 객체
}
✅ 배열선언
const arr1 = new Array();
const arr2 = new Array(3);
const arr3 = [];
✅ 배열에 값 저장
arr3[0] = "바나나";
arr3[1] = "사과";
arr3[9] = "키위";
✅ 배열 출력 : 기존 for 구문이용
모든배열의 요소가 출력. 값이 없는 경우 undefined 값
배열 요소 중 일부만 조회가능.
for(let i=0;i<arr3.length;i++){
console.log(`arr3[${i}] = ${arr3[i]}`);
}
✅ for in 구문
undefined 값은 출력안됨.
모든요소를 조회함
for(let i in arr3){
console.log(`arr3[${i}] = ${arr3[i]}`);
}
✅ 배열 관련 메서드( .indexof(요소) )
배열 .indexOf(요소) : 배열에서 요소의 위치값 리턴
<div class="area" id="area1"></div>
<button onclick="indexofTest();">확인하기</button>
<script>
function indexofTest(){
const area1 = document.querySelector("#area1");
const arr = ['사과','딸기','레드향','바나나','키위','한라봉'];
const search = prompt('위치를 찾고싶은 과일명 입력');
let index = arr.indexOf(search);
area1.innerHTML = `당신이 찾는 과일:${search}은(는)`;
if(index == -1){ // 리스트에 없는 경우
area1.innerHTML += "판매하지 않습니다.";
} else{
area1.innerHTML += `${index+1}번째 인덱스에 있습니다.`;
}
}
</script>
TEST
☑️ Q1. 간이 계산기 만들기
첫번째 값 : <input type="number" id="num1"><br>
두번째 값 : <input type="number" id="num2"><br>
<input type="button" value="+" onclick="calculator(this.value);">
<input type="button" value="-" onclick="calculator(this.value);">
<input type="button" value="x" onclick="calculator(this.value);">
<input type="button" value="/" onclick="calculator(this.value);">
<input type="button" value="%" onclick="calculator(this.value);"> <br><br>
계산결과 : <span id="result"></span>
✅ parseFloat : 사용자에게 두개의 숫자를 받아 문자열 → 정수로 저장
*사용자가 px, cm 등 단위까지 입력할 경우까지 고려하여 사용
let num1 = parseFloat(document.getElementById("num1").value);
let num2 = parseFloat(document.getElementById("num2").value);
let result;
✅ Number() vs parseFloat() 비교
- 정수와 소수를 입력할 경우 Number()와 parseFloat() 모두 정상 동작
- 숫자 뒤에 px, % 같은 단위가 붙으면 parseFloat()이 앞부분의 숫자만 추출
- 숫자로 시작하지 않으면 둘 다 NaN 반환
| 입력값 | Number() 결과 | parseFloat() 결과 |
| "123" | ✅ 123 | ✅ 123 |
| "123.45" | ✅ 123.45 | ✅ 123.45 |
| " 123.45 " | ✅ 123.45 | ✅ 123.45 |
| "123px" | ❌ NaN | ✅ 123 |
| "123.45px" | ❌ NaN | ✅ 123.45 |
| "abc" | ❌ NaN | ❌ NaN |
✅숫자가 아닌 값을 받을때 예외처리
if(isNaN(num1) || isNaN(num2)){
document.getElementById("result").innerHTML = "숫자만 입력해주세요";
return;
}
✅ 계산실행, 출력
*0으로 나눌경우 경고 메세지 출력
switch(val){
case "+" : result = num1 + num2; break;
case "-" : result = num1 - num2; break;
case "/" : result = num2 != 0 ? num1 / num2 : "0으로 나눌수 없습니다."; break;
case "%" : result = num1 % num2; break;
default : result = num1 * num2;
}
document.getElementById("result").innerHTML = result;
☑️ Q2. onmouseover, onmouseout 상태에 따른 이미지 변경
✅ querySelector() : 가장 첫 번째 일치하는 요소 하나만 반환
마우스 in,out 상태에 맞게 val 값에 맞는 name의 이미지 변경하는 메서드
function changeImg(val, state){
let img = document.querySelector(`img[name="m${val}"]`);
if(img){
let mode = ".jpg"; // 확장자 변경 가능
img.src = `images_01/${val}_${state}${mode}`;
}
}
// val 값에 맞는 name의 이미지 선택
let img = document.querySelector(`img[name="m${val}"]`);
✅ 파일 확장자 지정, 이미지 경로 변경
if(img){
let mode = ".jpg"; // 확장자 변경 가능
img.src = `images_01/${val}_${state}${mode}`;
}
✅ 실행메서드
function mover(val){
changeImg(val, "in")
}
function mout(val){
changeImg(val, "out")
}
☑️ 년도, 월을 선택하여 해당 달력 출력
✅ css
table { width:100%; border-collapse: collapse;}
th,td {border : 3px solid #bcbcbc; text-align: center; padding: 8px;}
th {background-color: #e2e2e2; color:#111111;}
td {background-color: #f2f2f2;}
caption {color:#111111; font-size: 20px; background-color: #ffffff;}
.text-red { color: red; }
.text-blue { color: blue; }
✅ Html
<select id="y">
<option>2023</option>
<option>2024</option>
<option>2025</option>
<option>2026</option>
</select>
<select id="m">
<option value="1">1월</option>
<option value="2">2월</option>
<option value="3">3월</option>
<option value="4">4월</option>
<option value="5">5월</option>
<option value="6">6월</option>
<option value="7">7월</option>
<option value="8">8월</option>
<option value="9">9월</option>
<option value="10">10월</option>
<option value="11">11월</option>
<option value="12">12월</option>
</select>
<input type="button" value="달력보기" onclick="show_cal()"><br><br>
<div id="cal"></div>
✅ Javascript
function show_cal() {
let y = document.getElementById("y").value;
let m = document.getElementById("m").value;
let firstDay = new Date(y, m - 1, 1).getDay(); // 해당 월의 1일의 요일
let lastDate = new Date(y, m, 0).getDate(); // 해당 월의 마지막 날짜
let dateNames = ['일', '월', '화', '수', '목', '금', '토'];
let cal = `<table><caption><strong>${y}년 ${m}월</strong></caption><tr>`;
// 요일 헤더 생성
for (let i = 0; i < 7; i++) {
cal += `<th class="${i === 0 ? 'text-red' : i === 6 ? 'text-blue' : ''}">${dateNames[i]}</th>`;
}
cal += `</tr><tr>`;
// 첫 주 빈칸 채우기
for (let i = 0; i < firstDay; i++) {
cal += `<td></td>`;
}
// 현재까지의 열 개수 추적
let dayCount = firstDay;
// 날짜 채우기
for (let day = 1; day <= lastDate; day++) {
let currentDay = (firstDay + day - 1) % 7; // 현재 요일 계산
let className = currentDay === 0 ? 'text-red' : currentDay === 6 ? 'text-blue' : '';
cal += `<td class="${className}">${day}</td>`;
dayCount++;
// 토요일이면 줄 바꿈
if (currentDay === 6 && day != lastDate) {
cal += `</tr><tr>`;
dayCount = 0;
}
}
// 마지막 행에 빈칸 추가해서 7칸 맞추기
let remainingCells = (7 - (dayCount % 7)) % 7;
for (let i = 0; i < remainingCells; i++) {
cal += `<td></td>`;
}
cal += `</tr></table>`;
document.getElementById("cal").innerHTML = cal;
}
window.show_cal();
☑️ 년도를 선택하여 해당 년도의 모든 월 달력 출력
✅css
.calendar-container {display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; margin-bottom: 30px;}
table { width: calc(100% / 4 - 20px); border-collapse: collapse;}
th,td {border : 3px solid #bcbcbc; text-align: center; padding: 8px;}
th {background-color: #e2e2e2; color:#111111;}
td {background-color: #f2f2f2;}
h3{text-align: center;}
.sunday { color: red; }
.saturday { color: blue; }
✅Html
<select id="y">
<option>2020</option>
<option>2021</option>
<option>2022</option>
<option>2023</option>
<option>2024</option>
<option selected="selected">2025</option>
<option>2026</option>
</select>
<input type="button" value="달력보기" onclick="show_cal()"><br><br>
<div id="cal"></div>
✅Javascript
function show_cal(){
const y = document.getElementById("y").value;
let cal = `<h3>${y}년</h3><br/><div class="calendar-container">`;
for(let m = 1; m <= 12; m++){
cal += callender(y,m);
}
cal += `</div>`;
document.getElementById("cal").innerHTML = cal;
}
// 달력 만드는 함수
function callender(y,m){
const firstDay = new Date(y,m-1,1).getDay();
const lastDate = new Date(y,m,0).getDate();
const dateDay = ['일','월','화','수','목','금','토'];
let cal = `<table><caption>${m}월</caption><tr>`;
// 일~월요일 표시
for(let i = 0; i < dateDay.length; i++){
cal += `<th class="${i == 0 ? 'sunday' : i == 6 ? 'saturday' : ''}">${dateDay[i]}</th>`;
}
cal += `<tr/><tr>`
// 해당 월 1일 앞 빈칸처리
for(let i = 0; i < firstDay ; i++){
cal += `<td></td>`
}
// 현재까지의 열 개수 추적
let dayCount = firstDay;
// 1~31일까지 일자 출력력
for(let day = 1; day <= lastDate; day++){
let currentDay = (firstDay + day - 1) % 7;
let className = currentDay == 0 ? 'sunday' : currentDay == 6 ? 'saturday' : '';
cal += `<td class="${className}">${day}</td>`;
dayCount++;
// 금요일 줄바꿈, 마지막일자 줄바꿈x
if(currentDay === 6 && day != lastDate){
cal += `</tr><tr>`
dayCount = 0;
}
}
// 마지막 행에 빈칸 추가해서 7칸 맞추기
let remainingCells = (7 - (dayCount % 7)) % 7;
for (let i = 0; i < remainingCells; i++) {
cal += `<td></td>`;
}
cal += `</tr></table>`;
return cal;
}
// 윈도우 실행시 바로 실행
window.show_cal();
PS. 달력 만들기 이제는 완전히 이해가 된 것 같다. 따로 한번 JAVA / JAVASCRIPT 두가지 버전으로 정리해야겠다.
'JavaScript' 카테고리의 다른 글
| [BCGD] 비전공자 백엔드 개발 도전기 (35) (2) | 2025.03.25 |
|---|---|
| [JavaScript] forEach/each/append/appendChild 총 정리 (0) | 2025.03.23 |
| [BCGD] 비전공자 백엔드 개발 도전기 (33) (1) | 2025.03.21 |
| [BCGD] 비전공자 백엔드 개발 도전기 (32) (0) | 2025.03.19 |
| [JS] 숫자 카운터 스크립트 (1) | 2024.09.13 |
