JavaScript

Do it : JS -8. 문서 객체 모델(DOM)

식초 2020. 10. 12. 09:31

문서 객체 모델(DOM)이란?

-Document Object Model

-웹 문서의  모든 요소를 자바스크립트를 이용하여 조작

-DOM은 객체를 사용해 문서를 해석한다 

-텍스트, 이미지, 표 등 모든 요소가 모두 객체이다

 

 

DOM 사용하지 않고 상세설명 가리기

-상세 설명이 가려지도록 CSS 작성

<h3 style="visibility : hidden">상세 설명</h3>

<p style="visibility : hidden">내용내용</p>

 

-매번 비쥬얼 스튜디오로 코드 편집은 번거로움 > 좀더 편하게 기능 추가할 방법 필요

 

 

DOM 사용하고 상세설명 가리기

-자바스크립트로 DOM 제어

-콘솔창에 입력> 상세 설명 사라진다

document.querySelector('#detail h3').style.visibility = 'hidden'

document.querySelector('#detail p').style.visibility = 'hidden'

 

-document는 웹 문서 자체를 가리키는 DOM 요소 중 하나이다 > 자바스크립트 웹 문서 소스 전부 인식 가능 > 수정도 가능

 

 

DOM 트리 - DOM 구조는 나무처럼 생겼다

-DOM은 부모 요소와 자식 요소로 구분한다

-노드(Node) : 네모 상자 : 문서의 요소 | 속성

-가지 : 얇은 선 : 노드와 노드 사이의 연결 관계

-html요소, 텍스트, 이미지 역시 자식 요소로 간주한다

 

-요소(Element) 노드 : 태그

-텍스트(Text) 노드 : 텍스트

-속성(Attribute) 노드 : 태그의 속성

-주석(Comment) 노드 : 주석

 

-DOM 트리 만들어지는 과정

-값이 없는 것은 줄바꿈 의미

-맨 위에 있는 것은 루트(Root) 노드

 

https://software.hixie.ch/utilities/js/live-dom-viewer/

 

Live DOM Viewer

Live DOM Viewer ... Script not loaded. This script puts a function w(s) into the global scope of the test page, where s is a string or object to output to the log. Some files are available for testing purposes, notably "image" is an image. image and image.

software.hixie.ch

 


DOM 요소에 접근하기

-자바스크립트로 프로그램에 사용할 요소에 접근하는 것

-주로 선택자를 사용한다

 

getElementById() - DOM 요소를 id 선택자로 접근하는 함수

-id 속성 값은 한 문서 안에서 유일하다

-콘솔창에 입력 > id값이 heading인 요소를 출력한다

document.getElementById("heading")

 

-제목을 누르면 접근한 요소의 글자 크기가 커지게 한다

document.getElementById("heading").onclick = function(){

    this.style.fontSize = "5em"

}

 

getElementsByClassName() - DOM 요소를 class 값으로 찾아내는 함수

-복수를 뜻하는 's'가 붙어있다

-2개 이상의 웹 요소에 접근한다

-콘솔창에 입력 > class 값이 accent인 요소를 출력한다

-HTMLCollection 값을 출력한다. 자료형식. 배열과 비슷

document.getElementsByClassName("accent")

▶HTMLCollection(2) [span.accent, span.accent]

-span요소 저장되어있음을 보여준다 > 마우스 올리면 해당요소 브라우저에서 보여준다

 

-1개 요소에만 접근하고 싶을 때 > 배열의 인덱스 사용

-첫번째 요소에 접근

document.getElementsByClassName("accent")[0]

 

-첫번 째 요소에 밑줄 표시하기

document.getElementsByClassName("accent")[0].style.textDecoration = "underline"

 

 

getElementsByTagName() - DOM 요소를 탸그 이름으로 찾아내는 함수

-이 함수도 s 붙어 있다 = 여러 돔 요소에 접근한다

 

-제목 첫번 째 요소에 배경색 넣어주기

document.getElementsByTagName("h2")[0].style.backgroundcolor = "#eee"

 

 

querySelector(), querySelectorAll() - DOM 요소를 다양한 방법으로 찾아주는 함수

-id, class값, 태그 이름 사용 가능

-querySelector()는 여러 요소 중 첫번째 요소에만 접근 가능

-id는 #붙이기

document.querySelector("#heading")

 

-class는 . 붙이기

document.querySelector(".accent")

▶NodeList(2) [span.accent, span.accent]

   노드리스트 : 여러개의 노드 모아 놓은 것, 배열과 비슷

-두번 째 요소에 배경색 노란색으로 바꾸기

document.querySelectorAll(".accent")[1].style.backgroundColor = "yellow"

 

 

getElementById() 함수와 querySelector()함수 차이점

-웹 요소만 변경 :  getElementById() 종류

-웹 요소 + 텍스트, 속성 변경 + 새로운 노드 추가 : querySelector() 종류

 

 


태그 속성 가져와서 수정

-속성 노드에 접근하면 HTML요소의 속성 값을 원하는 값으로 수정 가능

-선택한 상품 이미지 표시하기 프로그램

 : 웹 문서의 일부를 동적으로 변화

 

getAttribute(), setAttribute() - 태그 속성을 가져오거나 수정하는 함수

-선택한 상품 이미지 표시하기 프로그램 순서

1. 작은 이미지의 src속성에 접근해서 값 알아낸다 

2. 큰 이미지의 src속성에 접근해서 작은 이미지의 src값으로 변경한다

 

-이미지 요소에 접근 : querySelector()

-속성에 접근 : getAttribute()

-접근한 속성값 바꿈 : setAttribute()

 

1. 이미지src속성에 접근해서 값 알아내기

   콘솔 창에 입력 > 이미지에 접근하기 위해 이미지 소스 확인 : #prod-img > img (자식 선택자)

   document.querySelector("#prod-img>img").getAttribute("src")

 

2. 다른 이미지로 표시하기 = <img>태그의 src 속성을 바꾼다 = setAttribute()함수 사용

    괄호 안에 속성 이름속성값(바꿀 이미지 주소) 넣으면 된다

    document.querySelector("#prod-img>img").setAttribute("src", "image/coffee-blue.jpg")

 

 

선택한 이미지 표시 - 태그 속성 사용해 상품 이미지 변경

-원하는 위치에 이미지 표시 : getAttribute(), setAttribute()함수 사용

 

1. 큰 이미지 1개, 작은 이미지 3개

 

2. 큰 이미지 id값=cup, 작은 이미지 class값=small

 

3. 큰 이미지의 src 속성값을 작은 이미지의 src 속성 값으로 바꾼다

 

4. 자바스크립트 파일에 querySelector()함수를 사용해 큰 이미지 요소를 가져오고, 

   querySelectorAll()함수를 사용해 class값이 small인 작은 이미지를 가져온다

 

5. 작은 이미지에서 click 이벤트가 발생하면 showBig()함수 실행

-for문 사용 > smallPics 변수에 들어있는 각 요소에 접근

 

6. showBig()함수 만들기 

-작은 이미지 중 어떤 이미지를 눌렀는지 알아야 한다

-예약어 this가 가리키는 것 : click 이벤트 발생한요소=누른 작은 이미지

-this.src : 작은 이미지 파일 경로

-그 값을 가져와 bigPic 요소의 src속성에 지정

 

setAttribute()함수 대신 속성 사용

 


DOM에서 이벤트 처리

-addEventListener()함수 사용

 

이벤트 처리 방법 복습

 

HTML태그 에서 이벤트 처리기 연결

-이미지 눌렀을 때 다른 이미지로 바꿔 주는 changePic()함수 미리 선언

-<img>태그 안에 실행할 함수 연결 가능

-하나의 요소에 하나의 이벤트 처리기만 사용 가능

 

 

 

DOM요소에 이벤트 처리기 연결

-이벤트가 발생한 웹 요소를 가져온 후> 이벤트 처리기 연결하는 방법

-이벤트 처리기를 자바스크립트에서 실행한다

-이미지 요소를 가져와 pic 변수에 저장 후> click 이벤트가 발생했을 때> changePic()함수 실행

-하나의 요소에 하나의 이벤트 처리기만 사용 가능

 

addEventListener()함수 사용

-하나의 요소에 여러 이벤트 발생 > 동시 처리 가능

-보통 addEventListener()함수 많이 사용한다

 

1.  자바스크립트 문서에 이미지 요소 pic 변수에 지정, 

   changePic()함수, originPic()함수 선언,

   pic 변수에 지정된 요소마우스 커서 올려 놓으면 changePic()함수 실행

-이벤트 유형 : 이벤트 이름만 사용. on붙이지 않는다

-함수 : 이벤트가 발생했을 때 실행할 명령 나열

-캡쳐 여부 : 기본값 false (버블링: 자식 노드> 부모 노드로 이벤트 전달)

 

2. html문서 웹 브라우저에서 열고 마우스 커서 올리면 소년 이미지로 바뀐다.

   마우스를 치웠을 때이벤트 처리기 작성

   addEventListener()함수는 여러개 이벤트 처리기 연결 가능하므로!

 


스타일 가져와서 수정

-DOM의 역할은 웹 문서 요소를 동적으로 변화시킨다

 

DOM으로 CSS 속성에 접근, 수정

텍스트 색상 바꾸기

-스타일 속성에 접근할 때는 .style 예약어를 쓰고 > 그 다음 CSS 속성을 적는다

document.querySelector("#heading").style.color = "white"

-가운데 하이픈이 포함된 속성 >낙타 표기법 사용     ex. backgroundColor

document.querySelector("#heading").style.backgroundColor = "gray"

 

-마우스 포인터 올리면 초록원으로 바뀌는 사각형 : mouseover이벤트, mouseout이벤트

 

웹 요소를 화면에 표시/ 감추기

-display: none 사용 : 웹 요소 차지하던 공간도 사라진다 | display: block : 상세정보 화면 표시

-visibility: hidden 사용 : 웹 요소가 있던 공간은 빈 상태로 남아있는다.

 

 

상세 설명 보기/닫기 - 상세 설명 링크 만들기

-display속성 사용 

-[보기] 링크 누르면 내용 표시

-[닫기] 링크 누르면 내용 사라짐

 

1. [보기] 링크 눌렀을 때 내용 화면에 표시하는 소스

-링크 부분, 내용 부분의 선택자 확인!

- id="view", id="detail"

 

2. id="view"인 요소를 가져와 > 눌렀을 때 > #detail 요소의 display 속성 값을 수정(block으로)하는 소스

 

3. [닫기] 링크를 사용하기 위해 소스 수정

    #detail 내용이 감춰져 있는지 표시되어 있는지에 따라 > 실행할 명령이 2갈래 = if....else문 사용

 

4. 새로운 변수 isOpen 선언

- #detail 요소가 현재 화면에 표시된 상태인지 감춰진 상태인지를 저장하는 변수이다

-변숫값 : 표시 상태 | 감춰진 상태 2개 = 논리형

-초깃값 false : 기본적으로 #detail 요소는 감춰진 상태 이므로!

-맨 위에 추가한다 (변수 선언 소스끼리 모아 놓으면 좋음)

 

5. #view요소를 눌렀을 때 isOpen 변숫값을 체크하도록 소스 추가

 

6. #detail 영역이 감춰져 있을 때 실행할 명령문 = if문 안에 작성

 

7. #detail 영역이 표시되었을 때 실행할 명령문 = else문 안에 작성

 


DOM에 요소 추가

-참가 신청 명단 표시하기

-웹 문서 상에 없던 요소 추가해서 화면 표시

-이름 입력하면 바로 화면에 표시

-이름 추가할 때마다 DOM트리에 이름에 해당하는 새로운 노드 추가

 

DOM에 새로운 노드를 추가하는 방법

-사용자가 선택하는 옵션에 따라 새로운 내용을 웹문서에 표시해야한다

-DOM트리에 노드 추가

-요소 노드(태그) | 텍스트 노드(텍스트 내용) | 속성 노드(속성) | 주석 노드(주석)

-웹 문서 요소는 태그 속성과 내용을 함께 사용

 

-웹 문서에 어떤 소스를 추가할지 먼저 생각해야 한다

 

-새 노드 만들기, 부모 노드에 연결하기 위해서 다음 함수 사용

createElement() 요소 노드 만든다
createTextNode() 텍스트 노드 만든다
appendChild() 텍스트 노드를 자식 노드로 추가한다
createAttribute() 속성 노드를 만든다
setAttributeNode() 속성 노드를 연결한다
appendChild() 요소 노드를 부모 노드에 추가한다

 

웹 문서에 새로운 노드 추가

-웹 문서에 텍스트 단락 추가 > DOM트리에 새로운 노드 추가

 

1. 추가할 소스 생각하기

<body>태그 안에 ......<p class="accent">주문이 완료되었습니다</p> 추가하기

 

2. 요소 노드 만들기 - createElement()함수

-괄호 안의 요소에 해당하는 요소 노드를 적는다

-<p>태그에 해당하는 요소 노드를 만든다

-새로운 p요소를 만들고 newP 변수에 저장한다

var newP = document.createElement("p")

 

3. 텍스트 노드 만들기 - createTextNode()함수

-표시할 내용을 텍스트 노드로 만든다

-괄호 안에 내용을 입력한다

-newText 변수에 저장한다

var newText = document.createTextNode("주문이 완료되었습니다.")

 

4. 자식 노드로 추가하기 - appendChild()함수

-부모 자식 노드로 연결되지 않은 상태이다

-텍스트 노드 newText를 newP 노드의 자식 노드로 추가

-자식 노드가 여러개일 경우 > appendChild()함수를 사용한 노드는 맨끝에 추가됨

newP.appendChild(newText)

 

5. <p>태그 소스도 <body>태그 안에 추가해야 한다

-newP 노드를 body 노드의 자식 노드로 추가

document.body.appendChild(newP)

 

6. 속성 노드 만들기 - createAttribute()함수

-<p>태그에 class="accent" 속성 추가

-괄호 안에 추가할 속성 이름 지정

-새로운 class 속성 노드를 만들어  변수 attr에 저장

-attr.value를 사용해 속성값을 "accent"로 지정

var attr = document.createAttribute("class")

attr.value = "accent"

 

7. 속성 노드 연결하기 - setAttributeNode()함수

-p노드에 연결한다

-속성 노드를 요소 노드에 연결할 때는 위 함수 사용

-콘솔 창에  setAttributeNode()함수 실행하고 결과가 null 나오는 이유 : 속성 노드를 요소 노드에 연결하고 반환 값이 null이라는 뜻이다

newP.setAttributeNode(attr)

 

setAttribute()함수 사용

-더 간단히 속성 추가할 수 있다

newP.setAttribute("class", "accent")

   ||

var attr = document.createAttribute("class")

attr.value = "accent"

newP.setAttributeNode(attr)

 

 

참가 신청 명단 프로그램 - 새 노드 추가하고 표시하기

-이름 입력하고 [신청] 버튼 누르면 서버로 넘어감 

-서버 넘어가는 동시에 웹 브라우저에 표시

-신청 명단은 원래 웹 문서에 없던 것이기에 DOM 트리에 새로운 요소 만들기

 

1. 텍스트 필드에 이름 입력한 후 [신청] 버튼 누르면 가로줄 아래에 신청자 명단 표시

   html에서 <button>태그에 click 이벤트가 발생했을 때

   실행할 newRegister()함수 지정

   return false 추가 = 원래 버튼 기능(입력 내용을 서버로 전송하는 기능)을 사용하지 않겠다는 뜻

 

<button onclick = "newRegister(); return false;">신청</button>

 

2. 새로운 js파일 만들기, html과 연결하기

 

3. 새 요소 만들기

-newRegister()함수 작성

-<p>태그를 만든다

-새로운 p 요소를 만들고 newP 변수에 저장

 

4. 텍스트 노드 만들기

-텍스트 필드에 입력한 이름을 가져와 userName 변수에 저장

-creatTextNode()함수로 텍스트 노드 만들 때 userName값 사용

 

5. 텍스트 노드를 요소 노드에 연결

-appendChild()함수 사용해서 텍스트 노드 newText를 요소 노드 newP의 자식 노드로 연결한다

 

6. <p>태그를 <div id="nameList"></div>안에 들어가야 함

appendChild()함수 사용해서 newP요소를 nameList요소의 자식 노드로 연결

-userName.value ="";  다음 이름을 입력할 수 있도록 텍스트 필드 비운다

 


추가한 노드 : 순서 바꾸거나 삭제하기

-참가 명단의 순서 변경 및 삭제

-가장 최근에 추가한 이름을 화면 맨 위에 표시, 추가한 이름 삭제

 

노드 리스트 - 여러 노드를 한꺼번에 저장 

-참석자 명단 전체를 가져오려면 querySelectorAll("p")로 접근한다

-3개의 노드가 한꺼번에 저장되는데 이것을 '노드 리스트'라고 함

-콘솔창에 document.querySelectorAll("p")입력하면

 ▶NodeList(3) [p, p, p] 라고 뜬다 = 3개의 p노드가 배열 형식으로 저장

 

-특정 위치의 노드에 접근하려면 인덱스 사용

document.querySelectorAll("p")[0]

▼ <p>

       "홍길동"

       <span class = "del"> X </span>

   </p>

 

원하는 노드 다루기 - DOM트리 활용

-DOM트리는 부모, 자식, 형제 노드 관계 있다

-이 관계를 사용해서 원하는 노드에 접근한다 

-내용 삭제, 수정 가능

 

자식 노드 확인 - hasChildNodes()함수

-특정 노드에 자식 노드가 있는지 확인하는 함수

-자식 노드가 있다면 true, 없다면 false

document.querySelectorAll("p")[0].hasChildNodes()

true

 

자식 노드에 접근 - childNodes 속성

-자식노드 여러개 일 수 있다 = 복수형

-태그와 태그 사이의 줄바꿈빈 텍스트 노드 = 자식노드로 인식

-#nameList 요소의 자식 요소에 접근하자

document.querySelector("#nameList").childNodes

▶NodeList(7) [text, p, text, p, text, p, text]

text는 줄바꿈이다.

 

요소에만 접근 - children 속성

-저장된 자료형을 HTMLCollection 

-사용법은 배열과 같다

document.querySelector("#nameList").children

▶HTMLCollection(3) [p, p, p]

 

원하는 위치에 노드 삽입 - insertBefore()함수

-기준이 되는 노드를 지정하고 그 앞에 자식 노드 추가

-부모 노드를 가져와 nameList 변수에 저장

var nameList = document.querySelector("#nameList")

-2개의 인수 사용 (추가하는 노드, 기준이 되는 노드)

-3번째 이름을 맨 앞으로 옮긴다

nameList.insertBefore(nameList.children[2], nameList.children[0])

 

특정 노드 삭제 - removeChild()함수  parentNode속성

-removeChild()함수 : 부모 노드에서 자식 노드를 삭제하는 함수

-괄호 안에는 삭제하려는 자식 노드가 들어간다

-부모 노드에 접근한 후 부모 노드에서 삭제해야 함

-parentNode 속성 : 현재 노드의 부모 요소 노드를 반환

-부모 노드는 하나이므로 단수형

 

-첫번째 X를 삭제한다

<span class="del"> X </span> 요소 삭제 

-부모 노드 찾는다

document.querySelectorAll(".del")[0].parentNode

▼ <p>

      "홍길동"

      <span class="del"> X </span>

    </p>

 

-첫번째 p요소에서 removeChild()함수 실행

 

참가 신청 명단 프로그램 - 맨 위에 이름 추가

-최근에 입력한 이름을 명단 맨 위에 표시

 

1. appendChild()함수 사용해서 #nameList 요소에 p노드 추가한다

var nameList = document.querySelector("#nameList");

nameList. appendChild (newP);

-새로 추가하는 자식 노드가 맨 뒤에 추가된다

 

2. insertBefore()함수 사용해서 #nameList 요소에 p노드 추가한다

var nameList = document.querySelector("#nameList");

nameList. insertBefore (newP, nameList.childNodes[0]);

-새로 추가하는 자식 노드가 맨 앞에 추가된다

 

참가 신청 명단 프로그램 - 이름 삭제

1. 각 이름 오른쪽에 삭제 버튼 함께 추가한다

-영어 대문자 엑스(X)를 삭제 버튼으로 사용

<span class="del"> X </span>

 

2. register.js 파일 열어서 소스 추가

-텍스트 노드를 button 요소의 자식 요소로 추가하는 것이 중요!

 

3. 삭제 버튼 눌렀을 때 해당 이름 삭제하는 함수 작성해보자

-X버튼 추가할 때 class="del"속성 함께 사용

-class값을 식별자로 사용해 X버튼에 접근

var removeBttns = document.querySelectorAll(".del");

 

4. X버튼 눌렀을 때 어떤 노드를 삭제할 것인지 결정해야 함

-삭제해야할 노드는 p 노드이다. > p안에 span, 텍스트 모두 들어 있으므로!

-p 노드를 삭제하려면 id="nameList"인 div 노드=부모노드 에서 처리해야한다

-이벤트가 span노드에서 발생 > removeChild()함수는 > span 노드의 '부모 노드의 부모노드'에서 처리해야 한다

 

5. addEventListener()함수 사용해서 X버튼 누르는 이벤트해당 이름을 삭제하는 함수 연결

-X 버튼은 노드리스트 형태로 저장되어있다

-for문으로 removeBttns에 있는 노드리스트 요소 전체 반복

-사용자가 i번째 버튼에 click이벤트 발생시켰을 때 실행할 함수 연결

 

6. span노드(click 이벤트가 발생한 요소)에서 parentNode.parentNode로 접근한다

-this누른 삭제 버튼이다

'JavaScript' 카테고리의 다른 글

Do it : JS -10. 브라우저 객체 모델 (BOM)  (0) 2020.10.14
Do it : JS -9. 폼과 자바스크립트  (0) 2020.10.14
Do it : JS -7. Array 객체  (0) 2020.10.09
Do it : JS -6. 객체  (0) 2020.10.08
Do it : JS -5. 함수와 이벤트  (0) 2020.10.05