[JS] DOM

jung_ho9 개발일지·2022년 11월 10일
0

JavaScript

목록 보기
8/19
post-thumbnail

DOM


DOM은 Document Object Model의 약자로, HTML 요소를 Object 처럼 조작할 수 있는 Model을 의미한다. 즉, JavaScript를 사용할 수 있으면, DOM으로 HTML을 조작이 가능하다.

HTML 조작이란 ?


HTML문서를 분석하여 HTML의 아주 작은 부분까지 접근할 수있는 구조를 만들었는데 이렇게 만들어진 구조를 DOM이라고 한다. DOM을 이용하면 HTML로 구성된 웹 페이지를 동적으로 움직이게 만들 수 있다.

Script 삽입 위치


HTML에서 javaScript를 적용하기 위해서 <script> 태그를 사용한다.

<script src="index.js"></script>

웹 브라우저가 작성된 코드를 해석하는 과정에서 <script> 요소를 만나면, 웹 브라우저는 HTML 해석을 잠시 멈춤, HTML 해석을 잠시 멈추고 <script> 요소를 먼저 실행한다.

head안에 script 삽입하는 경우

HTML 문서를 파싱하는 중에 <script>태그를 만나 js파일을 받아오고 실행한 뒤, 다시 HTML문서를 파싱하게 됨.. Js 파일 크기가 엄청나게 클 경우 렌더링이 너무 오래걸리게 되어 사용자가 페이지를 보기까지 너무 오래걸릴 수 있기 때문에 좋은 방법이라고 보기는 어려움

body 끝나기 전에 script 삽입하는 경우

HTML 문서를 파싱을 먼저 하고 JS 파일을 받아오게 됨 body에 삽입하게 될 경우 화면 렌더링에서는 좀 효과적일 수 있으나 HTML파일 크기가 큰 경우 JS가 포함된 컨텐츠를 보기 위해서는 너무 오래걸릴 수 있음

async 속성을 사용하는 경우

asyncdefer은 HTML5에 새로 추가된 스크립트 속성이다. 이 두가지 속성은 HTML파싱과 스크립트 다운로드를 병렬로 진행함

async


HTML 문서와 같이 병렬적으로 파싱을 진행하다 JS 실행 단계에서는 HTML문서 파싱을 잠시 중지하고 JS실행이 끝나면 다시 HTML 문서 파싱을 재시작하기 때문에 HTML이 모두 실행되기 전 JS 가 실행되게 된다.

단! 다수의 스크립트 파일을 다운받게 되면 다운로드가 완료되는 순으로 JS 파일을 실행하기 때문에 순서에 상관없이 실행된다.

<script async src="index.js"></script>

defer


HTML 문서와 Js파일을 모두 다운로드 받아놓고 파싱이 끝난 순서대로 Js파일을 실행하기 때문에 원하는 방향으로 스크립트 실행 가능하다.

<script defer src="index.js"></script>

결론) 외부 스크립트를 불러올 때에는 defer 속성을 사용하는 것이 최선이고 순서 상관 없고 빨리 실행하는게 중요할 경우에는 async 속성 사용을 추천

DOM 다루기


document 객체에는 많은 속성과 메서드가 존재하지만, 지금 당장은 CRUD에 집중해야 한다.

CRUD란 ?


  • CREATE(만들기)
  • READ(조회하기)
  • UPDATE(갱신하기)
  • DELETE(삭제하기)

CRUD실습


querySelector

querySelector는 셀렉터를 조회한다는 의미를 가지고 있으며 class_div라는 class값을 가진 div의 엘리먼트의 정보를 divEl에 담아둘 수 있음

const divEl = document.querySelector('.class_div');

querySelectorAll

HTML문서 안에 class_div라는 클래스명을 가진 요소가 여러 개 일 때는 querySelectorAll을 사용함! 이렇게 조회한 HTML요소들은 배열처럼 for문을 사용할 수도 있음 하지만 진짜 배열은 아니 아닌 '유사 배열', '배열형 객체' 등 다양한 이름으로 부름

const divEl = document.querySelectorAll('.class_div');

createElement

document 객체 안에 있는 createElement는 지정한 태그의 HTML 요소를 만들어 반환함

const oneDiv = document.createElement('div'); 

classList

원래 지정 요소의 class 명을 읽을 수 있는 읽기 전용 속성이지만 여러 메소드를 사용하여 연결된 속성을 사용할 수 있음

  • add()
  • remove()
  • replace()
  • toggle()
    .......
classList.add를 이용해 oneDiv에 클래스 추가
oneDiv.classList.add('class_div')

textContent

위에서 생성한 oneDiv에 textContent라는 메서드를 활용하여 텍스트 컨텐츠를 추가할 수 있음

const Div = document.querySelector('.class_div')
Div.textContent = 'div입니다'

append

위에서 텍스트 컨텐츠를 추가한 후 화면에 보이게 하려면 append를 사용하여 기존의 트리구조에 연결시켜줘야 함

document.body.append(oneDiv)

innerHTML

innerHTML을 이용하여 body안에 모든 자식 요소를 간편하게 지울 수 있지만, innerHTML은 보안에서 몇 가지 문제를 가지고 있어 사용을 지양한다.

document.body.innerHTML = '';

🚫 XSS (Cross-Site Scripting) 공격에 취약하다는 약점을 가지고있음

innerHTML 사용을 권장하지 않는 이유

  • XSS 크로스 사이트 스크립팅에 취약하다.
    • 웹 해킹 공격 기법 중 하나로, 웹 사이트에 악성 스크립트를 주입하는 행위이다. XSS은 공격자가 상대방의 브라우저에 스크립트가 실행되도록 해 사용자의 세션을 가로채거나 웹 사이트를 변조, 악의적으로 콘텐츠 삽입, 피싱 공격을 하는 것을 말한다.

innerText

element 속성으로 해당 요소 내에서 사용자에게 보여지는 텍스트 값을 읽어온다. 연속되는 공백이 있을 시 하나의 공백으로 처리한다.

<div class="my_div">
	안녕하세요 !
	<span> 텍스트 <spna>
</div>

//innerHTML 출력 결과
안녕하세요! 텍스트

textContent

Node의 속성으로, innerText와 달리 <script><style>요소를 포함한 모든 요소의 콘텐츠를 값을 가져온다. 반면 innerText는 "사람이 읽을 수 있는" 요소만 처리한다.

textContent는 노드의 모든 요소를 반환하지만, innerText는 스타일링을 고려하며, "숨겨진" 요소의 텍스트는 반환하지 않는다.

<div class="my_div">
  안녕하세요 !
  <span> 텍스트 <spna>
</div>

    
// TextContent 출력 결과
안녕하세요! 
텍스트
  

removeChild

innerHTML 대신할 메서드인 removeChild는 자식 요소를 지정해서 삭제할 수 있음

해당 코드는 container에 자식 요소가 남아있지 않을 때까지, 첫 번째 자식 요소를 삭제함
const container = document.querySelector('#container');
while (container.firstChild) {
  container.removeChild(container.firstChild);
}

remove

remove 메서드는 DOM에서 요소를 제거할 수 있음

해당 코드는 tweet라는 클래스를 가진 모든 요소를 삭제함
const tweets = document.querySelectorAll('.tweet')
tweets.forEach(function(tweet){
    tweet.remove();
})

혹은 아래와 같이 for of 문도 가능 ⭕

해당 코드는 tweet라는 클래스를 가진 모든 요소를 삭제함
const tweets = document.querySelectorAll('.tweet')
for (let tweet of tweets){
    tweet.remove()
}

Element와 Node의 차이


Node?

태그, 텍스트, 주석 등을 모두 포함한 것

<!DOCTYPE html>
<html>
  <head>
    <title>My Page</title>
  </head>
  <body>
    <!-- Page Body -->
    <h2>My Page</h2>
    <p id="content">Thank you for visiting my web page!</p>
  </body>
</html>

위 문서는 다음과 같은 node 구조를 가지고 있음

DOCTYPE : html
HEML 
 ㄴHEAD
  ㄴTITLE
    ㄴ#text : My Page
  ㄴBODY
   ㄴ #comment : Page Body
   ㄴ H2 
     ㄴ#text : My Page
   ㄴ p id= "content"
     ㄴ#text : Thank you for visiting my web page!

element?

element는 node의 한 종류로 주로 <p> <div> 같은 태그를 사용해서 작성된 노드를 말함 위 문서의 element는 <html>,<head>,<title>,<body>,<h2>,<p>가 있음

주로 javaScript를 이용해서 DOM을 탐색하고 조작할 때는 이 element를 조작하는 경우가 많음

children과 childNodes의 차이


<body>
	<!-- 안녕하세요 -->
	<div>  
    	<h2>JUNGHO BLOG</h2>
    	<p id="content">블로그에 방문해주셔서 감사합니다!</p>
    <div>
<body>

childNodes

현재 요소의 자식 노드가 포함된 노드의 리스트를 반환 이때 태그노드, 텍스트노드, 주석 노드 모두 포함

출력 결과
NodeList(6)0: text 1: h2 2: text 3: p#content 4: text 5: divlength: 6[[Prototype]]: NodeList

children

HTMLCollection(3) [h2, p#content, div, content: p#content]

이벤트 객체


let menus = document.querySelectorAll("button");

let btnAmericano = menus[0];
let btnCaffelatte = menus[1];

btnAmericano.onclick = handleClick;
btnCaffelatte.onclick = handleClick; 
// for 문으로도 충분히 구현할 수 있는 내용입니다.

function handleClick(e) {
  let currentMenu = e.target; 
  console.log(currentMenu + "를 클릭하셨습니다.");
}
  • DOM과 JS 차이
  • createDocumentFragment
  • HTML5 template tag 사용법
  • 같은 엘리먼트를 appendChild 하면, 기존 엘리먼트를 복사할까?
  • offsetTop 등을 이용하여 좌표 정보를 조회할 수 있다.
  • offsetWidth 등을 이용하여 크기 정보를 조회할 수 있다.
profile
꾸준하게 기록하기

0개의 댓글