JAVA

26일차 2024 - 4 - 2

Domiseong 2024. 4. 2. 13:53

HTML element란? <> ... </> 를 의미한다.

 

 

■ JavaScript

★ 오늘은 HTML의 이벤트가 일어날 때가 언제일까?

1) HTML 웹 페이즈 로드가 완료되었을 때

2) HTML 이벽 필드가 변경되었을 때

3) HTML 버튼을 클릭했을 때

 

● button(버튼)을 클릭했을 때 어떤 element에서 실행이 되었을까?

→ target을 이용하여 console.log()로 확인할 수 있다. (어떤 태그에서 이벤트가 발생했는지)

 

● form 만들기 (부트스트랩 5 forms 예시 사용)

submit → 어떠한 액션을 요청할 수 있다.

요청이 들어오면 action 속성에 제출하게되고, onsubmit 속성의 반응을 받아온다.

 

onkeypress 속성 (= onkeydown 속성 + onkeyup 속성)

 

● onchange

→ 값을 다 입력하고 포커스를 옮길 때 이벤트를 발생

<script>
	function fun1() {
		console.log(event.target);	// 현재의 이벤트의 대한 정보를 얻을 수 있다.
		console.log("버튼 1이 클릭되었습니다.");
	}
	function fun2() {
		console.log(event.target);	// 현재의 이벤트의 대한 정보를 얻을 수 있다.
		console.log("버튼 2가 클릭되었습니다.");
		// <a> 엘리먼트가 기본적으로 가지고 있는 액션을 막음
		event.preventDefault();
	}
	function fun3() {  // submit에 대한 유효성을 검사하려는 함수
		console.log("사용자가 입력한 내용을 검사합니다.(유효성 검사)")
		// <form> 엘리먼트가 기본적으로 가지고 있는 액션을 막음
		event.preventDefault();
	}
	function fun4() {
		console.log("이메일 내용이 변경되었습니다.")
		console.log(event.target.value)
	}
	function fun5() {
		console.log("패스워드 내용이 변경되었습니다.")
		console.log(event.target.value)
	}
	function fun6() {
		console.log("체크 상태가 변경되었습니다.")
		if(event.target.checked){
			console.log("체크 됨")
		} else {
			console.log("체크해제")
		}
	}
</script>

// body태그 안의 form
<form action="/htmlcssjs" onsubmit="fun3()">
  <div class="mb-3 mt-3">
    <label for="email" class="form-label">Email:</label>
    <input onchange="fun4()" type="email" class="form-control" id="email" placeholder="Enter email" name="email">
  </div>
  <div class="mb-3">
    <label for="pwd" class="form-label">Password:</label>
    <input onkeyup="fun5()" type="password" class="form-control" id="pwd" placeholder="Enter password" name="pswd">
  </div>
  <div class="form-check mb-3">
    <label class="form-check-label">
      <input onchange="fun6()" class="form-check-input" type="checkbox" name="remember"> Remember me
    </label>
  </div>
  <button type="submit" class="btn btn-primary btn-sm">Submit</button>
</form>

fun1() ~ fun5() 까지 우리가 만든 것이 이벤트 처리 함수라고 한다.

 

※ 주의할 점

form태그 → action속성에 다른 브라우저로 이동하는 값이 들어가게 될 수 있다. 이를 방지하려면 event.preventDefault();

a태그 → href속성에 값이 들어가게 되면 그쪽으로 이동해버린다.. 이를 방지하려면 event.preventDefault(); 를 해당 함수에 넣어준다. (엘리먼트가 기본적으로 가지고 있는 액션을 막음)

onkeyup + 함수 event.target.value → 비밀번호 입력 확인

● 체크박스 확인하기
체크박스의 onchange속성에 함수를 연결하고, 함수에 event.target.checked로 확인

 

 

■ 예외처리

try, catch, finally,
throw → 거의 사용 안함

<script>
    function fun1() {
        try{
            var data;
            var num = data.length;
            console.log(num);
        } catch (err) {
            console.log("예외 발생");
            console.log(err);
        } finally {
            console.log("마무리 작업");
        }
    }
</script>

// body태그 안
<div class="card">
  <div class="card-header">exam20_try_catch</div>
  <div class="card-body">
    <button onclick="fun1()">버튼 1</button>
  </div> 
</div>

자바스크립트와 크게 다르지 않다.

 

 

■ HTML DOM

Document Object Model을 사용하면 JavaScript는 HTML 문서의 모든 요소에 액세스하고 변경할 수 있다.
https://www.w3schools.com/js/js_htmldom.asp

 

문서를 해석한다?  = 파싱한다.

 

● HTML DOM 객체 트리

상속관계는 아니지만 그렇게 보는 것이 전체적인 구조를 이해하는데 편하다.

<html> <title> <body> 등 모두 엘리먼트 타입으로 만들어짐
"속성"은 attribute 타입으로 만들어짐
Text는 텍스트 타입으로 만들어짐
이러한 타입들은 W3C 기관이 설계했다..
→ 이렇게 만들어진 구조를 DOM 이라 한다.

W3C 자바스크립트 레퍼런스에서 HTML DOM을 보고 공부하자.

 

(흐름 이해)
브라우저가 HTML을 쭉~ 해석(파싱)해서 객체(DOM)를 만들어낸다. ViewPort는 그 객체(DOM)을 화면에 렌더링하여 나타내준다.
자바스크립트는 객체(DOM)에 있는 내용을 변경/추가/삭제하면 렌더링을 바꿔주게 된다.(UI 변경/추가/삭제)

내가 그 객체를 사용하려면 그 객체의 메모리 번지를 알아야 한다. 그렇기 때문에 W3C HTML DOM에 대해 알아야 하는 것이다. 특정 객체의 어떠한 속성을 알고 수정할 수 있도록.

 

▶ DOM controller 생성

→ 컨트롤러를 새로 생성해주면 서버를 항상 재시작해주자!!

 

● BOM이란?

Browser Object Model

: 브라우저 객체 모델을 사용하면 자바스크립트가 브라우저와 "대화"할 수 있다.

 

★ BOM과 DOM의 차이점

1. BOM(Browser Object Model)
브라우저의 정보 또는 제어를 위해서 사용하는 객체 모델
(브라우저 창으로 제어 가능한 것들.. 뒤로가기(history 등)
  
2. DOM(Document Object Model)
HTML Document 내의 정보 또는 제어를 위해서 사용하는 객체 모델

 

# BOM 사용해보기

W3School - 자바스크립트 - 레퍼런스 → Window

<script>
    function fun1() {
        //ViewPort의 크기 얻기
        window.console.log("viewport width: ", window.innerWidth);  // 원래 window.을 붙여주어야 하지만, 생략 가능하다.
        console.log("viewport height: ", window.innerHeight);
    }
    function fun2() {
        // window.open(URL, name, specs, replace)
        // window.open("주소"); --> 새로운 윈도우 브라우저 창을 띄운다(팝업)
        console.log("Window open이 실행되었습니다.");
        window.open("https://www.w3schools.com", 
                "mywindow", 
                "top=100, left=200, width=350, height=500");
    }
    function fun3() {
        // window.location
        window.location.href="/htmlcssjs"
    }
    function fun4() {
        // window.history (이전 기록 화면으로 이동)
        window.history.back();
    }
    function fun5() {
        // window.history (다음 기록 화면으로 이동)
        window.history.forward();
    }
</script>

♣ 마우스 휠로 클릭했을 때 _blank를 지정하고, 왼쪽 마우스버튼으로 클릭했을 때 현재 윈도우창을 유지하며 이동하는 것 구현해보기.

 

Window 레퍼런스에 나와 있는 console, history, location, navigator, screen 은 window object 객체의 속성으로 이용된다.

 

● http와 https의 차이점은?

HTTPS는 데이터 보안을 위해 암호화된 연결을 제공하는 반면, HTTP는 보안이 취약한 연결을 제공합니다. 따라서 민감한 정보를 다루는 웹 사이트의 경우 HTTPS를 사용하는 것이 안전합니다.

 

 

■ 자바 스크립트의 배열(Array)

이벤트와 응용하여 실습해보았다.

● 배열 생성하고 값 읽기

<script>
    function basic(){
        console.log("basic() 실행");
        // 배열 생성
        const arr = ["Java", "JavaScript", "Vue.js"];
        // 배열 1인덱스 값 읽기
        console.log("arr[1]: ", arr[1]);
        console.log("배열의 길이: ", arr.length);
        // 배열 항목 변경
        arr[2] = "Spring";
        console.log(arr[2]);
        // 항목 반복 읽기 (방법 1)
        for(var i=0; i<arr.length; i++) {
            console.log(arr[i]);
        }
        // 항목 반복 읽기 (방법 2)
        // of는 항목을 가져오고, in은 항목의 인덱스를 가져온다.
        for(var item of arr){ 
            console.log(item);
        }
        for(var item in arr){
            console.log(item);
        }
    }
</script>

<!-- body태그 안에서 버튼으로 만들어 활용 -->
<p><button onclick="basic()" class="btn btn-outline-info btn-sm">기본</button></p>

→ 자바스크립트의 배열은 자바에서의 리스트와 비슷하다.

 

 

● 새 항목 추가해보기 (push)

<script>
    function appendItem(){
        console.log("appendItem() 실행");
        // 배열 생성
        const arr = ["java"];
        // 맨 뒤에 새 항목 추가
        arr.push("html");
        arr.push("css");
        // 항목 반복 읽기 (방법 1)
        for(var i=0; i<arr.length; i++) {
            console.log(arr[i]);
        }
    }
</script>

<!-- body태그 안에서 버튼으로 만들어 활용 -->
<p><button onclick="appendItem()" class="btn btn-outline-info btn-sm">새 항목 추가</button></p>

 

 

● 배열의 항목 제거 또는 삽입 (splice)

<script>
    function removeAndInsert(){
        console.log("removeAndInsert() 실행");
        // 배열 생성
        var arr = ["Banana","Orange","Apple","Mango"];
        // 항목 삭제
        // 항목을 삭제할 경우 뒤에 인덱스의 값이 앞으로 당겨옴
        arr.splice(2, 1); // 2 인덱스부터 1개를 삭제
        console.log(arr);

        // 항목 삽입
        arr = ["Banana","Orange","Apple","Mango"];
        arr.splice(2, 0, "Lemon", "Kiwi"); // 2 인덱스부터 0개를 삭제하고, 세번째 매개값 이후를 삽입
        console.log(arr);

        // 항목 대체
        arr = ["Banana","Orange","Apple","Mango"];
        arr.splice(2, 2, "Lemon", "Kiwi"); // 2 인덱스부터 2개를 삭제하고, 세번째 매개값 이후를 삽입
        console.log(arr);
    }
</script>

<!-- body태그 안에서 버튼으로 만들어 활용 -->
<p><button onclick="removeAndInsert()" class="btn btn-outline-info btn-sm">항목 제거 및 삽입</button></p>

→ 삭제 또는 삽입에 모두 splice가 쓰인다.

 

 

● 배열 합치기 (concat)

<script>
    function concatArray(){
        const arr1 = ["Banana","Orange"];
        const arr2 = ["Apple","Mango"];
        const arr3 = arr1.concat(arr2); // 자바와 차이점이 있다.(배열)
        console.log(arr1);
        console.log(arr2);
        console.log(arr3);
    }
</script>

<!-- body태그 안에서 버튼으로 만들어 활용 -->
<p><button onclick="concatArray()" class="btn btn-outline-info btn-sm">배열 합치기</button></p>

→ 서로 다른 두 개의 배열을 새로운 배열에 합쳐서 저장.

 

 

● 필터링 후 새로운 배열 생성

<script>
    function filterItem(){
         const arr = [  // 객체들이 들어있는 배열
              { bno: 1, title: "제목1", writer: "홍길동" },
              { bno: 2, title: "제목2", writer: "홍길서" },
              { bno: 3, title: "제목3", writer: "홍길남" },
              { bno: 4, title: "제목4", writer: "홍길서" },
              { bno: 5, title: "제목5", writer: "홍길북" },
            ];
         // filter() 메소드는 "배열"을 반환한다.
         // 방법 1
         const newArr = arr.filter((item) => { // 배열의 객체가 5개이기 때문에 5번 반복하여 필터링
             return item.writer === "홍길서" // 이 값이 true인 경우가 있더라면 반환해라.(filter()메소드는 배열을 반환시킴)
         });
         console.log("newArr: ", newArr);
         // 방법 2
         const newArr2 = arr.filter(item => item.writer === "홍길서");
         console.log("newArr2: ", newArr2);
         // 방법 3
         const newArr3 = arr.filter(item => item.bno%2 === 1);
         console.log("newArr3: ", newArr3);
         // 방법 4
         function filterFun(item){
             return item.writer === "홍길서";
         }
         const newArr4 = arr.filter(filterFun);
         console.log("newArr4: ", newArr4);
    }
</script>

<!-- body태그 안에서 버튼으로 만들어 활용 -->
<p><button onclick="filterItem()" class="btn btn-outline-info btn-sm">필터링 후 새로운 배열 생성</button></p>

→ 화살표 함수를 사용. 인덱스까지 받을 수 있지만, 필요한 경우 쓴다..

 

 

● 항목 찾기 (find)

<script>
    function findItem(){
        const arr = [  // 객체 배열
              { bno: 1, title: "제목1", writer: "홍길동" },
              { bno: 2, title: "제목2", writer: "홍길서" },
              { bno: 3, title: "제목3", writer: "홍길남" },
              { bno: 4, title: "제목4", writer: "홍길서" },
              { bno: 5, title: "제목5", writer: "홍길북" }
            ];
        // bno가 3인 게시물 찾기
        const board = arr.find(item => item.bno === 3);  // 조건이 true라면 값이 들어간다. 
        console.log(board);

        // writer가 홍길남인 게시물 찾기
        const board2 = arr.find(item => item.writer === "홍길남");
        console.log(board2);
    }
</script>

<!-- body태그 안에서 버튼으로 만들어 활용 -->
<p><button onclick="findItem()" class="btn btn-outline-info btn-sm">항목 찾기</button></p>

 

 

● 항목 일괄처리 (반복.. forEach 메소드를 사용해보자)

<script>
    function handleEachItem() {
        const arr = [  // 객체 배열
              { bno: 1, title: "제목1", writer: "홍길동" },
              { bno: 2, title: "제목2", writer: "홍길서" },
              { bno: 3, title: "제목3", writer: "홍길남" },
              { bno: 4, title: "제목4", writer: "홍길서" },
              { bno: 5, title: "제목5", writer: "홍길북" }
            ];
        // for : 인덱스를 이용하는 방법
        for(var i=0; i<arr.length; i++){
            console.log(arr[i]);
        }
        // for: of 이용
        for(var item of arr){
            console.log(item);
        }
        // 배열의 forEach() 메소드 이용 (많이 씀) (중요)
        arr.forEach( item => console.log(item) ); // 하나만 출력할 때
        arr.forEach(item => {  // 두 개 이상 출력할 때
            console.log(item.title);
            console.log(item.bno, item.writer);
        });
    }
</script>

<!-- body태그 안에서 버튼으로 만들어 활용 -->
<p><button onclick="handleEachItem()" class="btn btn-outline-info btn-sm">항목 일괄처리(반복처리)</button></p>

 

 

● 항목 변환하고 새로운 배열 생성

<script>
    function mapItem(){
        const arr = [  // 객체 배열
              { bno: 1, title: "제목1", writer: "홍길동" },
              { bno: 2, title: "제목2", writer: "홍길서" },
              { bno: 3, title: "제목3", writer: "홍길남" },
              { bno: 4, title: "제목4", writer: "홍길서" },
              { bno: 5, title: "제목5", writer: "홍길북" }
            ];
        // 제목으로 구성된 새로운 배열 얻기
        const titles = arr.map( item => item.title );
        console.log(titles);
        // 게시물 번호로 구성된 새로운 배열 얻기
        const bnos = arr.map( item => item.bno );
        console.log(bnos);
        // 항목에 오늘의 날짜를 date:'2024.4.2.'를 추가한 새로운 항목 배열을 얻기
        const newArr = arr.map( item => {
            var now = new Date();
            var strDate = now.getFullYear() + "." + (now.getMonth()+1) + "." + now.getDate();
            return {...item, date: strDate}
        });
        console.log(newArr);
    }
</script>

<!-- body태그 안에서 버튼으로 만들어 활용 -->
<p><button onclick="mapItem()" class="btn btn-outline-info btn-sm">항목 변환하고 새로운 배열 생성</button></p>

→ 화살표 함수를 사용.

 

 

● 항목 정렬 (sort)

<script>
    function sortItem(){
        const fruits = ["Banana","Orange","Apple","Mango"];
        // 올림차순으로 정렬
        fruits.sort();
        console.log(fruits);
        // 내림차순으로 정렬 (sort()를 한 후에 실행해야 함)
        fruits.reverse();
        console.log(fruits);
        // 객체 배열
        const arr = [
              { bno: 2, title: "제목1", writer: "홍길동" },
              { bno: 4, title: "제목2", writer: "홍길서" },
              { bno: 3, title: "제목3", writer: "홍길남" },
              { bno: 5, title: "제목4", writer: "홍길서" },
              { bno: 1, title: "제목5", writer: "홍길북" }
            ];
        // bno 기준으로 오름차순 정렬하기
        arr.sort( (item1, item2) => {
            return item1.bno - item2.bno; // 자바에서 comparable을 기억하자. -1일 때, 0일 때, +1일 때 를 구분하여 순서 정렬한다..
        } );
        console.log(arr);  // >> 출력은 비동기로 출력하기 때문에 하나씩 주석 처리하면서 실행해야 한다.
        // bno 기준으로 내림차순 정렬하기
        arr.sort( (item1, item2) => {
            return -(item1.bno - item2.bno);
        } );
        console.log(arr);
        // console.log()보다 arr.sort()의 실행문이 더 빨리 수행되기 때문에 위의 오름차순 정렬 콘솔 출력도 내림차순으로 나타나게 된다..

        // title 기준으로 내림차순 정렬하기
        console.log("제목1"<"제목2");
        arr.sort( (item1, item2) => {
            if(item1.title < item2.title){
                return 1;
            } else if(item1.title == item2.title){
                return 0;
            } else {
                return -1;
            }
        });
        console.log(arr);
    }
</script>

<!-- body태그 안에서 버튼으로 만들어 활용 -->
<p><button onclick="sortItem()" class="btn btn-outline-info btn-sm">항목 정렬</button></p>

→ 1차원 배열(객체를 담지 않은 배열)이 array라면, array.sort(compareFunction)

괄호를 비워주면 그냥 오름차순으로 정렬

단순한 값이 아닌 "객체"라면 괄호안에다가 사용자가 힌트를 제공해야 한다.

 

● 객체를 담고있는 배열에서 사용

function(a, b){return a-b}
* 상대적으로 정렬은 많이 쓰지 않는다.
→ 서버에서 정렬이 되어 내려오기 때문..?

 

 

※ 정리

자바와 비슷한 부분이 많지만.. 처음 써보는 함수들이 많았다. 그리고 람다식으로 일회용 함수로 사용하는 방법이 서툴다. 손에 익을 때까지 document를 보며 많이 사용해볼 수밖에 없다고 생각한다.