티스토리 뷰

일상코딩/노트

JavaScript : DOM

코딩애벌레 2024. 4. 16. 12:22

이제 웹의 구성을 모두 알게되는 파트다. 정적인 홈페이지에서는 크게 쓰이지 않던 언어가 2015년부터 동적 사이트가 유행하게되면서 필수요소가 되어버렸다. javascript의 역사나 지식은 크게 중요하다고 생각들지 않아서 스킵하고 바로 사용해보자. 나중에 이 언어로 백준을 풀어볼 날이 올까?


DOM(The Document Object Model)

: 웹 페이지를 구조화된 객체로 제공하여 프로그래밍 언어가 페이지 구조에 접근하는 방법을 제공한다. 이를 통해 문서의 구조, 스타일, 내용 등을 변경할 수 있다.

DOM API는 다른 프로그래밍 언어가 웹 페이지에 접근 및 조작 할 수 있도록 페이지 요소들을 객체 형태로 제공하며 그에 따른 메서드까지 제공한다.

javascript와 web page간에 DOM API를 통한 접근 및 조작
HTML 요소 자체를 관계로서 트리 구조를 나타내는 것 ( = DOM Tree)

 

: DOM에서는 모든 요소, 속성, 텍스트는 하나의 객체이며 브라우저는 HTML 문서를 해석하여 DOM tree라는 객체 트리로 구조화 되어있다.

: 위의 그림과 같이 document 객체의 하위 객체로 구성되어있으며 객체간 상속 구조가 존재한다

 


document

 

: 웹 페이지의 객체이며 DOM Tree의 진입점이다

: 페이지를 구성하는 모든 객체 요소를 포함하고있으며 가장 상위 객체이다

 

이를 이용해 일부 데이터를 변경해 나타낼 수 있다.

이 부분을 잘 편집해본적 없겠지만, 항상 html 파일 속 head에 있는 title부분이다.

 

이 부분을 console(바로 뒤에 나올 방법)을 통해 간단히 바꿔볼 수 있다.

지금까지 해왔던 방법으로는 html elements를 직접 수정해서 보는 방법이 있는데, 이 방법 말고 javascript 콘솔로도 가능하다.

 

위의 방법도 있지만, 

위의 방식으로 바꿀 수 있다!

 

방식이 조금 익숙한데, 간단하게 데이터를 조회해서 변수를 할당하고 바꾼다음에 출력하는 느낌이다. 어떻게보면 알고리즘 같고 어떻게보면 SQLite에서 출력하는 느낌이라고 생각이 든다. 바로 배우러 가볼까?


 

DOM 조작 3가지

 

1. HTML script 태그

html 파일 내부에서 설정하는 방법

 

html 의 body 마지막 부분에 추가하여 DOM을 조작하는 방법이다. 지금으로서는 가장 많이 사용하게될 방법이고 본문내용을 바로 보면서 할 수 있기 때문에 편리하다. 자동완성도 잘 되기때문에 실수할 일도 별로 없어서 해당 방법을 권장한다.

 

 

 

2. js 확장자 파일

 

따로 js 확장자 파일을 통해 관리해줄 수 있다. 이 경우 css와 동일하다고 보면 좋다. 문법 역시 동일하며 html에서 link를 걸어주는 방식과 동일하다. css를 head에 link하는 것과 달리 body 마지막 부분에 script src를 통해 등록한다. 

 

 

3. 브라우저 Console(콘솔)

브라우저 켜서 작성할 수 있다.

 

브라우저내에 Console창에서도 확인이 바로 가능하다. 대화를 주고받는 것처럼 대답을 해주는 형식이다. 다만 휘발성이니 확인용으로 사용하는 것이 좋을 것 같다. 좋은점은 개발자도구에서 경로 복사를 할 수 있다는 것인데, 간단하게 호출이 가능하다.

깔끔하게 경로가 복사되었다! html 탐색에서 굉장히 유용하다.


 

웹 페이지를 동적으로 만들기 == 웹 페이지를 조작하기

 

1. 조작할 요소를 선택 or 탐색

2. 선택된 요소의 컨텐츠 또는 속성을 조작

 

조작은 굉장히 간단하다.(명령어가 많을뿐..) 조작 하고자 하는 요소를 조회한 다음, 해당 요소의 콘텐츠, 속성 등을 조작한다. 그럼 드디어! 어떤 방법인지 알아보자.

 


선택 메서드
document.querySelector( *selector ) document.querySelectorAll( *selector )

- 제공한 선택자(*CSS selector)와 일치하는 element 한 개 선택

- 요소가 여러 개 일 경우 첫 번째 element 객체를 반환

- 요소가 없을 경우 null 반환


- 제공한 선택자(*CSS selector)와 일치하는 여러 element를 선택

- NodeList를 반환

 

 

위 처럼 작성했다면 확인해보자, html을 실행시키는 방법은 여러가지가 있지만 Alt + 'B' 커맨드를 입력하면 바로 켜진다. 출력은 html 화면이 아니라 개발자 도구인 F12의 Console 창에만 출력되는 것임을 인지하자!

 

잘 선택되어 출력된 것을 볼 수 있다.
All을 사용하여 조회하면 Node List로 반환되어서 데이터를 확인할 수 있는 모습이다.

 

 


속성 (attribute) 조작
클래스 속성 조작 일반 속성 조작
classList Attribute

element.classList.add()

지정 클래스 값 추가 element.getAttribute() 해당 요소에 지정된 값 반환
(조회)

element.classList.remove()

지정 클래스 값 제거 element.setAttribute()
지정된 요소의 속성 값을 설정

속성이 이미 있다면 기존 값 갱신 (덮어쓰기)


element.classList.toggle()


클래스가 존재한다면 제거하고
false
반환


클래스가 존재하지 않는다면
추가하고 true 반환


element.removeAttribute() 요소에서 지정된 이름을 가진 속성을 제거

 

위의 표를 따라 클래스 속성부터 조작해보자

 

참고로 javascript에서 변수 선언 시 const or let을 사용하니 알아두자!

궁금한 사람이 있을까봐 찾아봤는데, class 혹은 id가 아닌 속성값을 호출할 때는 다음 방법이 가능하다.

 


클래스 추가 : element.classList.add()

왼쪽 사진의 예시에서 'DOM 연습' 이라는 글씨를 빨간색으로 바꿔보려고 한다. 그렇다면 해당하는 태그에 style를 class에 넣어줘야할 것이다.

아까 개발자 도구에서 사용 가능한 경로 추적을 사용하여 붙여넣기하면 아주 편리하다.

  1. head에 style 내부에 .red (class 선택자)를 통해 crimson 색상을 추가한다.
  2. console.log 조회를 통해 내가바꿀 데이터가 맞는지 확인한다.
  3. const를 통해 h1Tag에 변수를 querySelector를 통해 선언해준다.
  4. class 추가 메서드인 add를 통해 'red' class를 추가해준다.

class에 red가 올바르게 추가된 모습을 확인할 수 있다.


클래스 삭제 : element.classList.remove()

이번에는 기존에 h1 태그 class 속 heading을 삭제해보자. 항상 그렇듯 삭제는 쉬운것 같다.

생성과 동일하게 선언 후 삭제만 해주면 된다.
heading은 삭제되고 위에서 추가했던 red만 남아있는 것을 확인할 수 있다.

 

같은 h1 태그를 다른 변수와 다른 CSS 선택자로 조회한 이유는 선택의 명확성을 위해서다. 물론 h1에 heading인 class가 있는 것을 알지만, 목적은 class로 heading이 들어간 항목을 찾는 것이었으므로, 결과는 동일하지만 과정은 살짝 다르다.


클래스 추가 or 제거 : element.classList.toggle()

toggle 은 직역하자면 '변환' 혹은 '교대 변경'을 의미한다. 프로그래밍에서 상태를 교대로 전환하거나 변경하는 동작을 나타내는데, 따로 on / off를 명시하는 것이 아니라 on이었다면 off로, off였다면 on으로 바꾸는 것을 의미한다. 따라서 요소에 특정 클래스가 존재한다면 해당 클래스를 제거하고, 존재하지 않는다면 추가하는 것을 의미한다. 그 예시로 다크모드가 있다.

 

그렇다면 삭제했던 heading을 생성하고 red를 다시 삭제해볼까??

 

위의 토글은 없어진 heading class를 다시 생성시켰고, 있었던 red class는 삭제된다
개발자도구에서도 확인할 수 있었다.
true / false로 바뀌는 것은 console로 확인할 수 있었다.

 

 

class와 id는 속성의 의미도 띄고 있기 때문에 아래의 방법들은 class와 id에서도 모두 공통으로 사용가능하다. 다만 주의사항이 있어서, 빨간 글씨를 꼭 확인하길 바란다!


속성 조회 : element.getAttribute()

이번에는 위에서 찾아본 것들을 복습하면서 class가 아닌 속성들을 접근해보자.

 

위의 조회는 가장 위에있는 a태그를 변수 지정하였으며, 변수 속 href 속성의 값을 가져온다. 따라서 console창에서 확인해보면 ?

제대로 google이 나오는 것을 확인할 수 있다.


속성 변경 : element.setAttribute(name, value)

조회를 해봤으면 변경도 해보자. 너무 어렵게 생각하지 않아도 된다. 조회한 데이터의 속성을 name에, value에는 바꾸고 싶은 값을 넣어주기만 하면 간단하게 변경된다.

주의할 점은 classList.add 처럼 추가되는 것이 아니라 기존의 데이터를 덮어쓰기 때문에 본래 있던 데이터는 삭제된다. 따라서 class에 추가할 경우에는 setAttribute를 사용하면 있었던 class value를 같이 써줘야해서 귀찮아진다.

name 값과 value값 모두 문자열임을 잊지말자!
console에서도 제대로 naver로 출력되는 것을 알 수 있다.

 

우리가 바꾼것은 href 속 값을 바꾼 것이기 때문에 글자 google을 바꾼것은 아니다. 조금 이따가 글자 바꾸는것도 나오니 조금만 기다리자!


속성 삭제 : element.removeAttribute()

언제나 속성은 간단하게 삭제할 수 있다. 위와 동일하게 조회 - 변수 설정 - 삭제 메커니즘을 따라가면 된다.

myAttr가 삭제된 것을 확인할 수 있다.

 



HTML 컨텐츠 조작

element.textContent = ' '

: 요소의 텍스트 컨텐츠에 접근할 수 있다.

: 문자열을 통해 직접 데이터를 조작할 수 있다.

 

링크를 조회하여 textContent를 출력한다
기존에 쓰여있던 textContent를 조회해서 console에서 google이 출력되었다

 

그렇다면 문자열로 내가 원하는 글자로 바꿔볼까? 아까 링크를 naver로 바꾸었기 때문에 텍스트도 네이버로 바꿔보자.

변수 할당하는게 제일 좋아~
문제없이 네이버로 바뀐 것을 볼 수 있다.



DOM 요소 조작
DOM 요소 조작 Method

document.createElement(tagName)

- 작성한 tagName의 HTML 요소를 생성하여 반환
Node.appendChild(Element) - 한 Node를 특정 부모 Node의 자식 NodeList 중 마지막 자식으로 삽입

- 추가된 Node 객체를 반환
Node.removeChild() - DOM에서 자식 Node를 제거

- 제거된 Node를 반환

 

복잡해보이지만 간단하다. 새로운 데이터를 생성해서 html에 추가하는 방법이라고생각하면 이해하기 쉽다. create를 통해 새로운 태그를 생성하고, 앞서 배운 textContent 을 추가하면 내부 text를 채우는 것이고, class나 id, Attr까지 모두 넣는 방법을 배웠을 것이다. 모두 짬뽕하면 된다! 맛있겠다

 

요소 생성 및 추가 : document.createElement(tagName),  Node.appendChild(Element)

본문마지막에 새로운 요소를 추가해 볼 예정이다. 이때, 생성만 중요한 것이아니라 넣을 위치를 찾는 것도 중요하다. appenChild를 사용하면서 위치를 NodeList 중 마지막 자식으로 삽입 되기 때문에 요소 조회를 잘 해줘야 한다.

넣을 위치를 탐색해서 자식으로 삽입시켜주는 것 까지가 요소를 추가하는 과정이다
Tag, class, id, attr, Text까지 모두 잘 추가된 것을 확인할 수 있다.


요소 제거 : Node.removeChild(Element)

제거 또한 부모 노드의 위치를 잘 설정해줘야 잘못 삭제되는 일이 없다.

이번에는 ul 태그 밑에 존재하는 li 중 마지막 요소를 삭제해보자.

 

n번째 요소에 접근할 때 :nth-child('숫자')를 통해 접근 가능하다. 위의 경우 li 태그중 3번째 것을 조회하겠다는 의미이다.

 

liTag를 탐색해준 후 부모 요소(Node)인 ulTag까지 조회해준다음 명령어를 통해 간단하게 삭제가 가능하다.

 

깔끔하게 삭제된 것을 확인할 수 있다.

 



style 조작

element.style.property = ' '

 

여기까지 왔으면 어려울 것 없다! textContent와 유사하게 style을 inline으로 넣어줄 수 있다. 이를 이용해 위에서 새로만든요소를 꾸며볼까?

 

아까 추가했던 h2Tag에 2px solid blue의 네모 박스를 추가해주었다
html에 inline요소로 추가되어있는 것을 확인할 수 있다.
콘솔에서도 자동완성을 보면서 확인할 수 있다. background를 추가해볼까?
변수는 이미 javascript 데이터에 있기 때문에 추가로 호출해 줄 필요는 없다.

 


부록

children과 childNodes의 차이

 

children은 html elements 타입들만 가져오게 된다.

childNodes는 node 타입이면 모두 가져온다(주석까지도)

 

CSS 선택자 사용 방법

명령어 한눈에 보기

   
    DOM 요소의 상위 객체
    documnet : DOM 트리의 최상위 객체
    documnet.documentElement : HTML 요소를 표현하는 객체
    document.body : body 요소를 표현하는 객체
    document.head : head 요소를 표현하는 객체

    DOM 요소의 자식과 부모 객체를 선택하는 방법
    - 자식으로 넘어갈 때의 경우
    bodyTag.children : body 요소의 자식 요소를 선택 (Element 타입)
    bodyTag.childNodes : body 요소의 자식 요소를 선택 (Node 타입)

    - 부모로 넘어갈 때의 경우
    child_1.parentElement : child_1 요소의 부모 요소를 선택 (Element 타입)
    child_1.parentNode : child_1 요소의 부모 요소를 선택 (Node 타입)

    DOM 조작 방법 (Javascript 사용)
    1. HTML 요소 찾기
    - (요즘 사용안함)document.getElementById('myId')
      : myId라는 id 속성을 가진 Element 요소를 찾음
   
      - document.querySelectior('cssSelector')
      : cssSelector라는 선택자를 가진 Element 요소를 찾음
   
      - document.querySelectiorAll('cssSelector')
      : cssSelector라는 선택자를 가진 모든 Element 요소를 찾음(NodeList 타입으로 반환)
   
   
    2. HTML 요소 변경하기
      - 텍스트 속성 변경 :
      .innerHTML : Element 내의 모든 HTML 수정
                    ex1) liTag.textContent = "아이템 1"
      .innerText : 시각적으로 보여지는 텍스트
                    ex2) liTag.innerHTML = "<strong>아이템 1</strong>"
      .textContent : 모든 텍스트

      - Element 속성 변경 :
      getAttribute('속성명') : 속성 값을 가져옴
                    ex1) divTag.getAttribute('myattr')
      setAttribute('속성명','값') : 속성 값을 뒤의 값으로 변경
                    ex2) divTag.setAttribute('myattr', 'newattr')

      - Element의 Class 속성 변경 (classList):
      .classList : 정보 확인용
      .classList.add('클래스명') : 클래스 추가
      .classList.remove('클래스명') : 클래스 제거
      .classList.toggle('클래스명') : 클래스 추가(true) 혹은 제거(false)
      .classList.contains('클래스명') : 클래스 포함 여부 확인
     
      - Element의 style 속성 변경
        - .style.color = 'red' : color 속성을 red로 변경
        - .style.backgroundColor = 'yellow' : backgroundColor 속성을 yellow로 변경
        * 스네이크케이스 경우 -가 연산자로 인식하기때문에 카멜 케이스 사용
   
    ### DOM 조작 (Element 생성)
    - newElement = document.createElement('태그명') : 새로운 Element 객체 생성
    - element.appendChild(newElement) : element의 자식으로 newElement 삽입
    - element.removeChild(childElement) : element의 자식 중 childElement 삭제
    - childElement.remove() : 해당 childElement 삭제
 
728x90

'일상코딩 > 노트' 카테고리의 다른 글

JavaScript : ReferenceType Function  (1) 2024.04.18
javascript : BasicSyntax  (0) 2024.04.17
Django : REST API 3  (0) 2024.04.15
Django : REST API 2  (0) 2024.04.12
Django : REST API 1  (0) 2024.04.11
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함