[BCGD] 비전공자 백엔드 개발 도전기 (34)

2025. 3. 22. 23:49·JavaScript
728x90

✅ 시계 구현하기

	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 두가지 버전으로 정리해야겠다.

728x90

'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
'JavaScript' 카테고리의 다른 글
  • [BCGD] 비전공자 백엔드 개발 도전기 (35)
  • [JavaScript] forEach/each/append/appendChild 총 정리
  • [BCGD] 비전공자 백엔드 개발 도전기 (33)
  • [BCGD] 비전공자 백엔드 개발 도전기 (32)
PUSH → MERGE → DEPLOY
PUSH → MERGE → DEPLOY
데이터 흐름과 운영 자동화를 설계하는 백엔드 개발자
  • PUSH → MERGE → DEPLOY
    Coding Dongin
    PUSH → MERGE → DEPLOY
  • 전체
    오늘
    어제
    • MEUN N
      • 코테(Solved.ac + Programmers) N
      • BootCamp(JAVA)
      • JAVA
      • SpringBoot
      • JavaScript
      • JSP
      • DB(SQL)
      • React
      • HTML_CSS
      • jQuery
      • SCSS
      • GSAP
      • 설치 + 꿀팁
      • 정보처리기사 오답노트
      • 정보처리기사 기출문제
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GIT
  • 공지사항

  • 인기 글

  • 태그

    프로그래머스
    dp
    배열
    level0
    level1
    정보처리기사 실기 기출문제
    수학
    자료구조
    Level2
    알고리즘
    시뮬레이션
    정처기실기
    자바
    java
    백엔드개발자
    solved.ac
    백준
    구현
    정렬
    실기
    코딩테스트
    브루트포스
    정보처리기사
    springboot
    정처기
    기출문제
    피보나치
    정처기오답노트
    완전탐색
    문자열
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.4
PUSH → MERGE → DEPLOY
[BCGD] 비전공자 백엔드 개발 도전기 (34)
상단으로

티스토리툴바