728x90
반응형

1. 문서 객체 모델 이해

문서 객체 모델 생성되는 방식/ 노드 타입 살펴보기

 

웹 브라우저: 문서 객체 모델(DOM) 생성할 수 있음

문서 객체 모델: 웹 브라우저에 표시되는 HTML 문서 구조를 객체화한 모델 구조

생성한 문서 객체 모델 ~> HTML 문서의 구성 요소를 객체로 인식

문서 객체 모델이 생성되는 방식

문서 객체 모델: 웹 브라우저) HTML 문서 해석 -> 객체로 변환 -> 웹 브라우저에 표시

=> 웹 브라우저에 표시되는 HTML 문서는 내부적으로 문서 객체 모델을 해석해서 보이게 됨

  • DOM 트리: 트리(tree) 구조 가짐
    • 노드(node): document 객체 하위에 HTML 태그 요소, 속성, 텍스트, 주석 등 트리 형태로 구성
      -> 부모, 자식, 형제 관계 형성
    • 루트 노드(root node): DOM 트리의 가장 꼭대기(최상위)에 있는 노드(ex. html/ document - 객체)

      
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document Object Model</title>
</head>
<body>
<h1>header</h1>
<a href="#">link</a>
</body>
</html>


노드 타입 살펴보기

문서 객체 모델은 CSS 포함 X => CSS와 관련 있는 노드 타입 X

  • 문서 노드(Node.DOCUMENT_NODE): 최상위 document 객체
  • 요소 노드(Node.ELEMENT_NODE): h1, p 태그와 같은 요소
  • 속성 노드(Node.ATTRIBUTE_NODE): href, src와 같은 속성
  • 텍스트 노드(Node.TEXT_NODE): 텍스트
  • 주석 노드(Node.COMMENT_NODE): 주석

2. 노드 선택

속성/ 메서드

 

자바스크립트로 웹 브라우저에 표시되는 HTML 문서 조작 -> 문서 객체 모델 조작

=> window 객체의 document 객체 사용해 조작할 수 있음(조작하려는 문서 객체 모델의 노드 선택)

속성

  • (+) 노드 타입 가리지 X 모든 노드 이동하며 선택할 수 있음
  • (-) DOM 트리가 복잡할수록 원하는 노드 찾아가기 어려움
모든 노드 탐색 parentNode 부모 노드를 반환
childNodes 모든 자식 노드를 반환
firstChild 첫 번째 자식 노드를 반환
lastChild 마지막 자식 노드를 반환
previousSibling 이전 형제 노드를 반환
nextSibling 다음 형제 노드를 반환
요소 노드 탐색 parentElement 부모 요소 노드를 반환
children 자식 요소 노드를 반환
firstElementChild 첫 번째 자식 요소 노드를 반환
lastElementChild 마지막 자식 요소 노드를 반환
previousElementSibling 이전 요소 노드를 반환
nextElementSibling 다음 요소 노드를 반환

      
// document 객체로 접근할 수 있는 html 노드로 이동 -> firstChild 속성
document.firstChild; // <DOCTYPE html>
// 첫 번째 자식 요소 노드로 이동 -> firstElementChild
document.firstElementChild; // html
// 연속으로 사용
document.childNodes[1].firstElementChild.firstElementChild.nextElementSibling;

메서드

속성값과 태그명 사용 - get 메서드

  • getElementById(<id 속성값>)
    • id 속성값과 일치하는 요소 노드를 1개만 선택
    • 해당하는 요소 하나만 보여 줌
  • getElementsByClassName(<class 속성값>)
    • class 속성값과 일치하는 요소 노드를 모두 선택
    • *HTMLCollection 객체로 여러 요소 한꺼번에 선택
  • getElemenetsByTagName(<태그명>)
    • 태그명과 일치하는 요소 노드를 모두 선택
    • *HTMLCollection 객체로 여러 요소 한꺼번에 선택

*HTMLCollection 객체: 유사 배열 -> 배열의 인덱스로 요소에 하나씩 접근 가능


      
<script>
// id 속성값이 title인 요소 노드 1개 선택하기
const el = document.getElementById("title");
console.log(el);
// class 속성값이 text인 요소 노드 모두 선택하기
const classEl = document.getElementsByClassName("text");
console.log(classEl);
console.log(classEl[0]);
console.log(classEl[1]);
// p 태그에 해당하는 요소 노드 모두 선택하기
const tagEls = document.getElementsByName("p");
console.log(tagEls);
console.log(tagEls[0]);
console.log(tagEls[1]);
</script>

 

CSS 선택자 사용 - query 메서드

  • querySelector(<CSS 선택자>)
    • 매개변수로 넘어오는 CSS 선택자에 해당하는 노드를 1개만 선택
  • querySelectorAll(<CSS 선택자>)
    • 매개변수로 넘어오는 CSS 선택자에 해당하는 노드를 모두 선택
    • NodeList 객체에 담아 반환

      
<body>
<div class="box-1">
<p class="text">text-1</p>
<p class="text">text-2</p>
</div>
<div class="box-2">
<p class="text">text-3</p>
<p class="text">text-4</p>
</div>
</body>

      
<script>
// class 속성값이 box-1인 요소 노드 선택
const el = document.querySelector(".box-1");
// class 속성값이 box-1인 요소의 하위에 있는 p 태그
const el = document.getElementsByClassName("box-1")[0].children; // HTMLCollection 객체
const el = document.querySelectorAll(".box-1 .text"); // NodeList 객체
</script>

3. 노드 조작

콘텐츠/ 스타일/ 클래스/ 데이터/ 메서드

콘텐츠

  • textContent
    • 요소 노드의 모든 텍스트에 접근
    • 단순히 텍스트로 취급 -> 그대로 노드의 콘텐츠에 넣음
  • innerText
    • 요소 노드의 텍스트 중 웹 브라우저에 표시되는 텍스트에만 접근
    • 태그로 인식해 노드의 콘텐츠에 적용
  • innerHTML
    • 요소 노드의 텍스트 중 HTML 태그를 포함한 텍스트에만 접근
    • 단순히 텍스트로 취급 -> 그대로 노드의 콘텐츠에 넣음

      
<p id="title">Hello, <span style="display:none;">Javascript!</span></p>
<script>
document.getElementById("title").textContent; // Hello, Javascript!
document.getElementById("title").innerText; // Hello,
document.getElementById("title").innerHTML; // Hello, <span style="display: none;">Javascript!</span>
</script>

      
<p id="textContent"></p>
<p id="innerText"></p>
<p id="innerHTML"></p>
<script>
document.querySelector("#textContent").textContent = `<strong>textContent</strong> 속성`;
document.querySelector("#innerText").innerText = `<strong>innerText</strong> 속성`;
document.querySelector("#innerHTML").innerHTML = `<strong>innerHTML</strong> 속성`;
</script>

  • innerHTML 속성에 값 할당 -> 태그로 인식해 노드의 콘텐츠에 적용
  • But, textContent 속성, innerText 속성 -> 단순히 텍스트로 취급 => 값을 그대로 노드의 콘텐츠에 넣음

스타일

  • <노드>.style.<css 속성명> = <속성값>;
  • querySelector() 메서드: 스타일 조작하고 싶은 노드 선택
  • 선택한 노드에 style 속성으로 조작하고 싶은 CSS 속성명 적고, 적용하고 싶은 CSS 속성값 할당
    • 카멜 표기법 사용 ex. background-color -> backgroundColor

      
<p id="text">text</p>
<script>
const pEl = document.querySelector("p"); // 노드 선택하기
pEl.style.backgroundColor = "#ff0000";
pEl.style.fontSize = "20px";
pEl.style.color = "#ffffff";
</script>

클래스

  • <노드>.classList.add("class 속성값"); // 추가
  • <노드>.classList.remove("class 속성값"); // 삭제
  • <노드>.classList.toggle("class 속성값"); // 추가와 삭제 반

      
<style>
.red-color{
color:red;
}
.fz20{
font-size:20px;
}
</style>
(중략)
<p id="text">text</p>
<script>
const pEl = document.querySelector("#text"); // 노드 선택하기
pEl.classList.add("red-color");
pEl.classList.add("fz20");
</script>

데이터

data-* 속성

  • 사용자 정의(custom) 속성
    • HTML 문법에서 사용 O 속성 외에 사용자가 원하는 속성을 추가할 수 있음
  • 자바스크립트의 dataset 속성 사용해 조작

      
<button data-cnt="10">가방 구매</button>
<button data-cnt="0">신발 구매</button>
<script>
// querySelectorAll() 메서드: 복수의 노드 선택
const buttonEls = document.querySelectorAll("button");
// forEach() 메서드: 반복해서 각 노드에 접근
buttonEls.forEach((el) => {
// dataset 속성으로 data-cnt 속성 정보 가져와 출력
console.log(el.dataset);
console.log(el.dataset.cnt);
})
</script>
// 실행결과
/* dataset 속성으로 노드의 data-* 속성에 대한 정보 가져옴,
정보 -> DOMStringMap 객체에 담겨 반환 */
// 객체 속성에 접근 -> 정확하게 data-cnt 속성 값만 가져옴


메서드

모든 속성을 전체적으로 조작

  • <노드>.getAttribute("속성명");
    • 속성값 가져옴
    • 모든 속성의 상위 메서드 -> classList 속성이나 dataset 속성으로 하는 조작 할 수 O
  • <노드>.setAttribute("속성명", "속성값");
    • 속성값 설정
    • 모든 속성의 상위 메서드 -> classList 속성이나 dataset 속성으로 하는 조작 할 수 O
  • <노드>.removeAttribute("속성명");
    • 속성 삭제

      
<a href="https://www.gilbut.co.kr">길벗</a>
<script>
// querySelector() 메서드: a 태그에 해당하는 요소 노드 선택
const aEl = document.querySelector("a");
// getAttribute() 메서드: href 속성값 가져옴
const href = aEl.getAttribute("href");
// setAttribute() 메서드: 속성값 새로 설정
aEl.setAttribute("href", "https://www.sucoding.kr");
aEl.innerText = "수코딩";
// 속성값 적용해 새 창으로 열리게
aEl.setAttribute("target", "_blank");
</script>

 

*classList 속성과 setAttribute() 메서드

classList 속성으로 class 속성값 추가/삭제 -> 기존 요소가 가지고 있던 class 속성값을 보존하면서 추가/삭제

=> 이미 class 속성 O -> 단순히 추가되는 형태

But, setAttribute() 메서드: 아예 속성값 새로 설정 => 기존 class 속성값 보존 X


4. 노드 추가/ 삭제

노드 추가/ 삭제

노드 추가

노드 생성 createElement() 요소 노드 생성
createTextNode() 텍스트 노드 생성
createAttribute() 속성 노드 생성
노드 연결 <기준 노드>.appendChild(<자식 노드>) 기준 노드에 자식 노드 연결
<기준 노드>.setAttributeNode(<속성 노드>) 기준 노드에 속성 노드 연결

      
<!DOCTYPE html>
<html>
<head>
<title>Create Node</title>
</head>
<body>
<script>
// 요소 노드 생성
// 요소 노드: 주축이 되는 노드
const aEl = document.createElement("a");
// appendChild() 메서드 ~> 생성된 노드 -> 기존 DOM 트리와 연결
document.body.appendChild(aEl);
// 텍스트 노드 추가
const txtEl = document.createTextNode("길벗");
document.querySelector("a").appendChild(txtEl);
// href 속성 노드 추가
const hrefAttr = document.createAttribute("href");
hrefAttr.value = "https://www.gilbut.co.kr";
// a 요소 노드의 자식 노드로 추가 X
document.querySelector("a").setAttributeNode(hrefAttr);
</script>
</body>
</html>


노드 삭제

<부모 노드>.removeChild(<자식 노드>)


      
// p 요소 노드 찾아서 삭제
<body>
<p>text 1</p>
<a href="https://www.gilbut.co.kr">길벗</a>
<a href="https://www.sucoding.kr">수코딩</a>
<script>
const pEl = document.querySelector("p");
pEl.parentNode.removeChild(pEl);
</script>
</body>
// DOM 트리 순회하면서, a 태그에 해당하는 요소 노드 모두 삭제
<body>
<p>text 1</p>
<a href="https://www.gilbut.co.kr">길벗</a>
<a href="https://www.sucoding.kr">수코딩</a>
<script>
const childNodes = document.body.childNodes;
childNodes.forEach((node) => {
if(node.nodeName === "a")
node.parentNode.removeChild(node);
})
</script>
</body>

5. 폼(form) 조작

form 태그 선택하기/ 폼 요소 선택하기/ 폼 요소의 입력값 다루기

form 태그 선택하기

  • forms 속성
    • document 객체의 forms 속성 -> 모든 form 태그의 노드 정보를 HTMLCollection 객체에 담아 반환
    • => (+) 화면에 있는 form 요소 노드 쉽게 선택할 수 있음
    • (HTMLCollection 객체: 유사 배열 -> 인덱스 ~> form 요소 노드에 하나씩 접근 O)
    • (-) form 태그의 위치 변경 -> 잘못 참조 => 오류 발
  • name 속성
    • (+) 직관적으로 form 요소 노드 선택할 수 있음
    • (+) form 태그 순서 변경 상관 X

폼 요소 선택하기

  • elements 속성
    • form 요소 노드의 하위 노드 중 폼 요소 노드만 반환하는 속성
    • HTMLFormControlsCollection 객체에 여러 개의 노드 담아 반환
      HTMLFormControlsCollection 객체: form 요소 노드의 하위에 있는 폼 요소 노드의 정보 담겨 있음
  • name 속성
    • name 속성값으로 노드 참조할 수 있게 데이터 정의

=> 폼 요소에 접근: 인덱스/ name 속성값 


      
<body>
<form name="frm1">
<label for="uname">이름</label>
<input type="text" id="uname" name="uname">
<label for="age">나이</label>
<input type="text" id="age" name="age">
<label for="gender">성별</label>
<select id="gender" name="gender">
<option value="male">male</option>
<option value="female">female</option>
</select>
<button type="submit">전송</button>
</form>
</body>

      
document.frm1.elements[0]; // 0번 인덱스 노드
document.frm1.elements['uname']; // form 요소 노드의 하위 노드 중 name 속성값이 uname인 노드
// elements 속성 생략하고 name 속성값으로 바로 접근
document.frm1.uname;
document.forms[0].gender;

폼 요소의 입력값 다루기

  • 한 줄 입력 요소 다루기
    • input 태그의 type 속성값: text, password, number, url, search, email 등
    • value 속성: 사용자가 입력한 값 가져오기
  • 여러 줄 입력 요소 다루기
    • textarea 태그

      
// 한 줄
<form name="frm">
<input type="text" name="id">
<input type="password" name="pw">
</form>
<script>
document.frm.id.value = 'jscoding';
document.frm.pw.value = 'aaaccc';
</script>
// 여러 줄
<form name="frm">
<textarea name="desc"></textarea>
</form>
<script>
document.frm.desc.value = 'setting!';
</script>
  • 체크박스
    • checked 속성: 체크 표시 있는지 확인
      • 체크된 상태 -> checked 속성에 true를 할당
    • value 속성: 값 가져옴
  • 라디오버튼
    • 여러 개의 항목 중 하나만 선택하게 할 때 사용하는 폼 요소
    • checked 속성: 선택됐는지 확인
    • value 속성: 값 가져옴
  • 콤보박스
    • select 태그
    • 여러 항목에서 하나를 선택하는 형태의 폼 요소
    • selected 속성: 선택 항목 확인
    • value 속성: 값 가져옴
  • 파일 업로드 요소
    • <input type="file" name=upload">
    • files 속성으로 반환되는 FileList 객체

      
const files = document.frm.upload.files;
files[0].name; // 파일 이름
files[0].size; // 파일 크기
files[0].type; // 파일 타입
files[0].lastModifiedDate; // 파일 마지막 수정일

 

*폼 요소 관련 기타 메서드

  • submit(): 폼 요소의 값을 전송(submit)
  • focus(): 폼 요소에 포커스(커서)를 이동

6. 이벤트(event) 다루기

이벤트 종류/ 이벤트 등록

 

이벤트: 웹 브라우저와 사용자 사이에 상호작용이 발생하는 특정 시점

이벤트 종류

마우스 이벤트 onclick 마우스로 클릭하면 발생
ondblclick 마우스로 빠르게 두 번 클릭하면 발생
onmouseover 마우스 포인터를 올리면 발생
onmouseout 마우스 포인터가 빠져나가면 발생
onmousemove 마우스 포인터가 움직이면 발생
onwheel 마우스 휠(wheel)을 움직이면 발생
키보드 이벤트 onkeypress 키보드 버튼을 누르고 있는 동안 발생
onkeydown 키보드 버튼을 누른 순간 발생
onkeyup 키보드 버튼을 눌렀다가 뗀 순간 발생
포커스 이벤트 onfocus 요소에 포커스가 되면 발생
onblur 요소가 포커스를 잃으면 발생
폼 이벤트 onsubmit 폼이 전송될 때 발생
리소스 이벤트 onload 웹 브라우저의 리소스 로드가 끝나면 발생

이벤트 등록

이벤트가 발생할 때 어떤 작업을 할지 자바스크립트 코드로 작성하는 것

 

인라인 

  • HTML 태그에 속성으로 이벤트를 등록하는 방법

      
// 입력창 클릭 -> 커서 활성화 => onfocus 이벤트 발생
// 입력창 외부 영역 클릭 -> onblur 이벤트 발생 => 블러(focus out) 상태
<form>
<input type="text" onfocus="focusEvent()" onblur="blurEvent()">
</form>
<script>
function focusEvent(){
console.log("focus on");
}
function blurEvent(){
console.log("focus out");
}
</script>

 

* 포커스 이벤트 사용 시 주의할 점

코드 내부에 경고창 나타내는 alert() 메서드 사용 X (경고창 무한)

  • 경고창 클릭 -> 입력창에서 커서 빠져나갔다고 판단 => onblur 이벤트 발생
  • 경고창 닫히면서 커서 다시 입력창 들어가서 onfocus 이벤트 발생

프로퍼티 리스너(property listener)

  • 요소 노드에 직접 속성으로 이벤트를 등록하는 방법

      
<button>클릭</button>
<script>
const btnEl = document.querySelector("button");
btnEl.onclick = function(){
alert("click");
}
// 화살표 함수
btnEl.onclick = () => {
alert('arrow click');
}
// 함수 별도 정의, 함수명 이용 -> 이벤트와 연결
btnEl.onclick = clickEvent;
function clickEvent(){
alert('click');
}
</script>

 

이벤트 등록 메서드

  • DOM에서 제공하는 addEventListener() 메서드 사용
  • <노드>.addEventListener("<이벤트 타입>", <이벤트 함수>);

      
<button>클릭</button>
<script>
const btnEl = document.querySelector("button");
btnEl.addEventListener("click", function(){
alert("button Click");
});
// 화살표 함수 or 함수 선언문이나 함수 표현식으로 정의한 함수명으로 연결
// 함수 표현식으로 정의된 함수 -> (호이스팅) 선언, 할당 분리
// => 참조하려는 함수 addEventListener() 메서드보다 반드시 위에 작성
const clickEvent = () => {
alert("button Click");
}
btnEl.addEventListener("click", clickEvent);
</script>

7. 이벤트 객체와 this

이벤트 객체 사용하기/ 이벤트 취소하기/ this 키워드 사용하기

 

이벤트 객체

  • 이벤트 타입에 따라 발생하는 이벤트의 각종 정보가 들어 있는 객체 집합
  • 개발자가 직접 생성 X, 이벤트 발생 -> 실행되는 함수의 매개변수로 같이 전달

이벤트 객체 사용하기

  • 클릭 이벤트의 PointerEvent 객체의 주요 속성
    • clientX: 마우스가 클릭된 Y좌표(수평 스크롤 포함 X)
    • clientY: 마우스가 클릭된 Y좌표(수평 스크롤 포함 X)
    • pageX: 마우스가 클릭된 x좌표(수평 스크롤 포함 O)
    • pageY: 마우스가 클릭된 Y좌표(수평 스크롤 포함 O)
    • screenX: 모니터의 왼쪽 위 모서리를 기준으로 마우스가 클릭된 x좌표
    • screenY: 모니터의 왼쪽 위 모서리를 기준으로 마우스가 클릭된 x좌표
  • KeyboardEvent 객체의 주요 속성
    • keyCode: 키보드에서 눌린 키의 유니코드 값 반환
    • ctrlKey: Ctrl 키 눌렸으면 true, 아니면 false
    • altKey: alt 키 눌렸으면 true, 아니면 false
    • shiftKey: shift 키 눌렸으면 true, 아니면 false

이벤트 취소하기

HTML 태그 중 일부: 기본으로 이벤트 적용

=> preventDefault() 메서드: 태그에 기본으로 연결된 이벤트 취소


      
// a 태그에 연결된 클릭 이벤트 취소
<a href="https://www.naver.com">네이버 이동</a>
<a href="https://www.daum.net">다음 이동</a>
<script>
const aEls = document.querySelectorAll("a");
for(let i = 0; i < aEls.length; i++){
aEls[i].addEventListener("click", function(e){
// 기본 이벤트 취소
e.preventDefault();
});
}
</script>

this 키워드

  • 이벤트가 발생한 요소 노드 바로 가리킴
  • 이벤트 발생 시점에 대상 노드 조작할 수 있음
  • 화살표 함수 -> this 범위 달라져 this가 이벤트 발생 노드 가리키지 X
    • this가 window 객체 가리킴
    • => 이벤트 객체의 target 속성 사용

      
// 기존 코드에서 p 태그 클릭 -> 텍스트 색상: red/ 이미 red -> black
<script>
const pEls = document.querySelectorAll("p");
pEls.forEach((el) => {
el.addEventListener("click", function(){
if(this.style.color === 'red'){
this.style.color = 'black';
}else{
this.style.color = 'red';
}
});
})
// 화살표 함수
// (X)
/* pEls.forEach((el) => {
el.addEventListener("click", () => {
console.log(this);
});
}) */
// (O)
pEls.forEach((el) => {
el.addEventListener("click", (e) => {
console.log(e.target);
});
})
</script>

출처

 

코딩 자율학습 HTML + CSS + 자바스크립트

더북(TheBook): (주)도서출판 길벗에서 제공하는 IT 도서 열람 서비스입니다.

thebook.io

 

728x90
반응형
김앩옹