assignment
review
이벤트
8. 이벤트
- 웹 페이지에서 발생하는 사건, 자극을 의미
- 이벤트를 통해서 사용자와 상호작용이 가능
- 마우스나 키보드의 움직임
1) 이벤트종류
- 사용자의 동작이나 브라우저의 상태가 변경됨을 의미
- 마우스이벤트 : click, mouseover, mouseout...
- 키보드이벤트 : keyup, keydown
- 폼이벤트 : change, submit...
- 윈도우이벤트 : load, resize, scroll
2) 이벤트핸들러
- 이벤트가 발생되면 실행하는 함수
[예]
<p id = "text" style = "cursor: pointer;"
onclick="changeColor()">텍스트클릭하기</p>
changeColor가 이벤트 핸들러함수
onclick="changeColor()" 브라우저의 text라는 id로 정의된 요소에소 click이벤트가 발생
하면 changeColor 함수를 실행하라고 등록하는 코드
3)이벤트리스너(event Listener)
- 이벤트를 감시하고 이벤트핸들러와 실제 소스객체를 연결
4)이벤트 연결하는 방법
①이벤트핸들러속성
② 표현식을 이용해서 이벤트속성에 함수등록
③ addEventListener를 이용해서 등록
- 표준방식
- 이벤트핸들러로 정의한 함수가 호출될때 자바스크립트엔진이 자동으로 함수에 event객체를 전달한다.
[형식]
addEventListener(type, function(e){ -> 전달되는 이벤트객체를 사용
-------- 사용하지 않으면 매개변수에 정의하지
이벤트종류 않아도 된다.
click, keyup
mouseover....
})
---------
이벤트가 발생되면 실행할 함수
5) 이벤트동작(이벤트흐름)
- 이벤트가 발생하면 부모요소를 거쳐 타겟요소까지 찾아 내려가고 다시 부모에서 최상위까지 전파
- stopPropagation을 이용해서 버블링이 발생해도 부모이벤트가 발생하지 않도록 작업
- 원래 기존 태그가 갖고 있는 특성대로 실행되는 것을 막기 위해 preventDefault()를 이용
① 이벤트캡처링
- 이벤트가 최상위요소에서 이벤트가 발생된 타겟요소까지 내려가는 단계
② 타겟인지
- 이벤트가 발생한 타겟에서 이벤트처리로 등록한 함수가 실행
③ 이벤트 버블링
- 이벤트가 타겟요소에서 최상위로 다시 올라가는 단계
DOM

window.onload = function() let form = document.querySelector("#todoForm"); // 폼
let input = document.querySelector("#todoInput"); // 입력창
let list = document.querySelector("#todoList"); // 할 일 목록
= 위의 3개를 가져오는 이유: 내가 조작할 부분의 태그를 가져와서 각각의 변수에 넣음. 내가 누르는 곳, 만들어지는 곳, 클릭한 곳.
= 자바스크립트는 HTML 태그를 직접 만질 수 없으니까, querySelector로 태그를 가져옴
form.addEventListener("submit", function(e) {
e.preventDefault(); // 기본 새로고침 막기
let todoText = input.value;
alert(todoText); // 테스트
});
새로고침을 막고 자바스크립트로 할 일을 받아 오고 테스트 하기
= 1) form에 이벤트 연결 -> 추가 버튼을 눌렀을 때 submit은 항상 새로고침이 됨. 그러면 밑에 항목이 추가가 되지 않기 때문에 새로고침을 막아서 자바스크립트로 밑에 할 일을 추가할 수 있도록 준비하는 단계.
= 2) todoText = input.value 입력창에 적은 글자를 자바스크립트 코드로 가져오기.
html파일에 리스트로 표현하라는 태그가 있음.
ul이란 전체적인 틀이 있고 항목들은 내가 li들을 만들어야 함.
1) li 태그 만들기
let new태그 = document.createElement("태그이름");
createElement : HTML 안에 아직 존재하지 않는 태그를 자바스크립트 코드로 새로 생성
Element : HTML에서 태그 1개를 의미
2) 안에 글자 넣기
newItem.textContent = todoText;
let textnode = document.createTextNode(todoText);
list.appendChild(newItem)
list.appendChild(newItem)
2) 이제 li태그에 입력한 값이 들어가 화면에 표시됨 하지만 글자가 계속 남아있음 그래서 초기화를 시켜줌
input.value = ""; // 다음 입력을 위해 입력창 비우기
<ul id="todoList">
<li>공부하기</li> ← 현재까지 한것
</ul>

<li>
<span>공부하기</span> // 텍스트도 따로 구분해야 삭제나 수정이 편함.
<button>완료</button>
<button>삭제</button>
</li>
window.onload = function() {
let form = document.querySelector("#todoForm");
let input = document.querySelector("#todoInput");
let list = document.querySelector("#todoList");
form.addEventListener("submit", function(e) {
e.preventDefault();
let todoText = input.value;
//alert(todoText); // 테스트용
let newItem = document.createElement("li");
/*newItem.textContent = todoText;*/
let textnode = document.createTextNode(todoText);
newItem.appendChild(textnode);
list.appendChild(newItem);
/*input.value = "";*/
let span = document.createElement("span");
/*let textnode = document.createTextNode(todoText);*/ /*span.textContent = todoText;*/
span.appendChild(textnode);
input.value = "";
});
}
window.onload = function() {
let form = document.querySelector("#todoForm");
let input = document.querySelector("#todoInput");
let list = document.querySelector("#todoList");
form.addEventListener("submit", function(e) {
e.preventDefault();
let todoText = input.value;
//alert(todoText); // 테스트용
// li 만들기
let newItem = document.createElement("li");
// 글자(textnode) 먼저 만들기
let textnode = document.createTextNode(todoText);
/*newItem.textContent = todoText;*/
/*span.textContent = todoText;*/
// span 만들기
let span = document.createElement("span");
// textnode를 span 안에 붙이기
span.appendChild(textnode);
// span을 li 안에 붙이기
newItem.appendChild(span);
// li를 ul 안에 붙이기
list.appendChild(newItem);
/*let textnode = document.createTextNode(todoText);*/
/*span.textContent = todoText;*/
// 입력창 비우기
input.value = "";
});
}
let doneBtn = document.createElement("button");
let delBtn = document.createElement("button");
버튼에 텍스트 넣는 3가지 방법
1. textContent : 가장 안전하고 간단함.
= 태그가 아닌 글자형태로 들어감
2. innerText : 화면에 눈에 보이는 텍스트만 다룸
= 숨겨진 글씨는 무시, 사실상 1번이랑 비슷함
3.innerHTML : HTMl 태그를 해석해서 넣음
= HTMl 태그를 직접 쓸 수 있음
4. appendChild(createTextNode) : 정석 DOM 방식
= 과정이 길지만 내부구조를 직접 만듦.
appendChild() : 부모노드의 자식노드로 새로운 노드를 추가
// 버튼에 텍스트 추가
doneBtn.appendChild(document.createTextNode("추가"));
delBtn.appendChild(document.createTextNode("삭제"));
// 버튼을 li안에 붙이기
newItem.appendChild(doneBtn);
newItem.appendChild(delBtn);
doneBtn.addEventListener("click", function() {
/*alert("완료 버튼 눌림!"); // 테스트*/
newItem.classList.toggle("done")
});
li.done span {
text-decoration: line-through;
color: #999;
}
]li 태그에 done 클래스가 있을때 그안의 span에 즐 긋기
newItem.classList.toggle("done");
= 뜻 : li 태그(newItem)에 done이라는 클래스를 붙였다 뗐다 해라
. 의미= newItem 자체가 객체라 점을 이용해서 그 안의 속성이나 기능에 접근함. 쉽게 말해 객체 안의 무언가를 꺼내겠다라는 뜻
classList : 이 태그가 가진 class 속성들 모음
toggle("done") : li태그에 done 클래스가 없을 때 추가됨 있으면 제거되고 스위치 같이 on/off 같은 기능

삭제 버튼
delBtn.addEventListener("click", function(){
newItem.remove();
});
강사님이 하신 코드에서 공부할 것
// ✅ 1. todolist의 항목값을 저장할 빈배열
let todoArray = [];
// ✅ 2. 새로운 할 일(todoItem)을 객체로 만들어 배열에 추가
const todoItem = {
id: Date.now(),
text: newTodoText,
done: false
};
todoArray = [...todoArray, todoItem];
// ✅ 3. 삭제할 때 (filter로 특정 id만 제외)
todoArray = todoArray.filter(item => item.id !== id);
// ✅ 4. 완료 토글할 때 (map으로 done 값을 반대로 변경)
todoArray = todoArray.map(item =>
item.id === id ? {...item, done:!item.done} : item
);
배열을 쓴 이유 :
1. 상태를 저장할 수 있음
= 할 일을 추가하거나 삭제하거나 완료했을 때,
그 “현재 상태”를 배열 안에 그대로 저장할 수 있음.
2. 화면을 다시 그리기 가능
3. 추가/삭제/수정이 너무 쉬워짐
추가
삭제
수정
todoArray = todoArray.map(item =>
item.id === id ? {...item, done: !item.done} : item
);
객체들 정리




assignment
review
https://nodejs.org/ko[노드js](https://nodejs.org/ko)



컴포넌트를 씀으로써 돔 api를 안씀. -> 리액트를 쓰는 이유
assignment
review
라우팅 프로젝트 생성 후 폴더 이동 후 React Router라이브러리를 설치
= npm install react-router-dom
설치 확인

main.jsx에서 컴포넌트를 BrowserRouter로 감싸준다.

폴더 만듦. - rafce

다시 공부하기
import React from "react";
import User from "./User";
const UserList = (userlist) => {
console.log(userlist);
return (
<div>
{userlist.users.map((user) => (
<User
key={user.id}
id={user.id}
name={user.name}
addr={user.addr}
/>
))}
</div>
);
};
export default UserList;
assignment
review
웹 구조
= 웹 서버 : 분석하고 응답하는 일밖에 못함 -> 컨테이너에게 정보를 넘기고 표준화된 폴더구조(컨텍스트 - 웹 파일, web-znf- web.xml, lib, classes(자바파일들)) , 서블릿에게 넘김(서블릿이 요청을 받아주는 역할 그럼 요청) -> DB ->DBMS 다시 반대로 돌아서 요청을 돌려줌
컨테이너와 서블릿에 대한 이해 필요!
HTML, CSS, javascript - DOM이 복잡하고 화면도 복잡해서 만들어 낸게 react
DOM이 나오기전에 DOM을 편하게 해주는 jquery를 씀
서버쪽 뒤에서 안보이는데에서 처리되는 것 : 백엔드
자바 webwork - 프로젝트 생성 - dynamic web - 이름 backend - next

dd파일 web.xml 체크

생성 완료

정보가 저장되는 곳

서버가 인식하는 곳

프론트엔드는 배포를 했어서 있고 백엔드는 아직 없음

html 실행 always 체크

백엔드도 생김

서버가 자바코드를 찾는 위치, 서블릿디렉토리라고 함

서블릿 등록 하는 곳 -> 밑에 source 탭으로 바꿈

서블릿의 lifecycle을 설명하기 위한 전체적인 흐름
= 요청받은 객체(request)가 메모리에 로딩 됐는지 확인 -> 서블릿 객체를 생성하고(객체는 한번만 생성되고 웹서버가 쓰레드 생성함. 이 안에서 서비스가 호출되고 똑같이 요청방식에따라 doget, dopost로 됨. 요청이 들어올때 마다 쓰레드를 생성. 즉 자신만의 공간을 만든다.) init 메소드 호출 -> service호출 -> 매개변수로 request(클라이언트의 요청정보를 담는 객체), response(클라이언트에게 응답할 정보를 담을 객체)를 만듦. -> get인지 post인지 확인하고 doget, dopost로 db에 접근 -> 서비스가 응답정보를 서블릿컨테이너로 보냄 -> 컨테이너는 자바를 실행할 능력은 있는데 응답할 능력은 없어서 웹서버로 전달하고 -> 응답해줌





<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://jakarta.ee/xml/ns/jakartaee" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" id="WebApp_ID" version="5.0">
<display-name>backendtest</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>first</servlet-name>
<servlet-class>basic.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>first</servlet-name>
<url-pattern>/basic/first.iot</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>second</servlet-name>
<servlet-class>basic.SecondServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>second</servlet-name>
<url-pattern>/iot/second</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>life</servlet-name>
<servlet-class>basic.ServletLifeCycleTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>life</servlet-name>
<url-pattern>/life.html</url-pattern>
</servlet-mapping>
</web-app>
assignment
review

흐름

https://blog.naver.com/heaves1/224075584701
과정 잘 정리해놓을 것 - 구조는 spring가서 똑같음.
for(MemberDTO member:userlist) {
out.print("<tr>");
out.print("<td>"+member.getId()+"</td>");
out.print("<td>"+member.getPass()+"</td>");
out.print("<td>"+member.getName()+"</td>");
out.print("<td>"+member.getAddr()+"</td>");
out.print("<td>"+member.getDeptno()+"</td>");
out.print("<td>"+member.getPoint()+"</td>");
out.print("<td> <a href = '/backendtest/member/delete?id="+ member.getId() +" '>삭제</a></td>");
out.print("</tr>");
}
redirect vs forward
= 전혀 다른개념
자바는 왜 서블릿과 jsp를 쓸까?
= 화면 분리를 해놔서 이제 html에 자바를 써야 하는데 html에 자바를 써야 해서 jsp를 쓴다.
jsp :실행할때 서블릿 코드로 변환되서 실행됨
MVC 패턴
http : stateless 상태정보가 유지가 안됨, 쿠키나 세션으로 유지
register(뷰) - 서블릿(컨트롤러) -> dAO(모델) -> DBMS
^ |
|--------------jsp(뷰)
스프링 시작
인텔리제이 설치





-프로젝트만들기







