Space
article thumbnail
Published 2023. 6. 10. 18:59
[JS] DOM (2) JavaScript
반응형

DOM 활용 (CRUDA)

 
DOM의 기초적으로 활용하기 위해서 
Create (생성) / Read (읽기) / Update (갱신) / Delete (삭제) / Append (적용)
하는 법을 알아보겠습니다.

 


생성 (Create)

// createElement
const oneDiv = document.createElement('div');  // oneDiv 변수에 <div> tag를 생성한다.
console.log(oneDiv);                           // <div></div>

// createTextNode
const textNode = document.createTextNode('Banana');

 


읽기 (Read)

// querySelector
// 입력한 선택자와 일치하는 문서 내의 첫 번째 요소를 반환한다.
// 일치하는 요소가 없다면 null을 반환한다.
// id, class, tag 전부 가능하다.
const container = document.querySelector('#container'); // id명이 container인 첫 번째 요소 선택
const container = document.querySelector('.container'); // class명이 container인 첫 번째 요소 선택
const container = document.querySelector('container');  // tag명이 container인 첫 번째 요소 선택


// querySelectorAll
// 입력한 선택자와 일치하는 모든 요소를 반환한다.
// id, class, tag 전부 가능하다.
const items = document.querySelectorAll('#item'); // id명이 item인 모든 요소 선택
const items = document.querySelectorAll('.item'); // class명이 item인 모든 요소 선택
const items = document.querySelectorAll('item');  // tag명이 item인 모든 요소 선택
// querySelector 대신 getElementById, getElementsByClassName, getElementsByTagName을 사용할 수 있다.
// getElementById
// 입력한 id명과 일치하는 문서 내의 첫 번째 요소를 반환한다.
// id만 가능하다.
const itemId = document.getElementById('item');  // id명이 item인 첫 번째 요소 선택


// getElementByClassName
// 입력한 class명과 일치하는 문서 내의 첫 번째 요소를 반환한다.
// class만 가능하다.
const itemClass = document.getElementByClassName('item');  // class명이 item인 첫 번째 요소 선택


// getElementByTagName
// 입력한 Tag명과 일치하는 문서 내의 첫 번째 요소를 반환한다.
// Tag만 가능하다.
const itemTag = document.getElementByTagName('item');  // Tag명이 item인 첫 번째 요소 선택
반응형

갱신 (Update)

// textContent
// 노드의 텍스트를 변경한다.
const oneDiv = document.createElement('div');  // oneDiv 변수에 <div> tag를 생성한다.
oneDiv.textContent = 'hello';                  // text를 변수에 추가한다.
console.log(oneDiv);                           // <div>hello</div>
// classList.add
// 노드에 클래스를 추가한다.
const oneDiv1 = document.createElement('div');  // oneDiv1 변수에 <div> tag를 생성한다.
oneDiv1.classList.add('hi');                    // 입력한 선택자를 변수에 추가한다.
console.log(oneDiv1);                           // <div class="hi">hello</div>
// nodeValue
// 텍스트 노드 객체 값을 반환한다.
// 문서, 요소 노드를 참조하면 null을 반환한다.
const oneDiv = document.createElement('div');  // oneDiv 변수에 <div> tag를 생성한다.
oneDiv.classList('hi');                        // <div class="hi"></div>
oneDiv.textContent('hello');                   // <div class="hi">hello</div>
const oneDivFirstChild = oneDiv.firstChild;    // hello 선택 

console.log(document.nodeValue);               // null   (문서 노드 참조)
console.log(oneDiv.nodeValue);                 // null   (요소 노드 참조)
console.log(oneDivFirstChild.nodeValue);       // hello  (텍스트 노드 참조)
<!-- replaceChild(newChild, oldChild) -->
<!-- 자신을 호출한 노드의 자식 노드인 oldChild를 newChild 노드로 교체한다. -->

<!DOCTYPE html>
<html>
  <body>
    <ul id='fruits'>
      <li>Apple</li>
    </ul>
  <body>
  <script>
    const $fruits = document.getElementById('fruits');
    
    // 기존 노드와 교체할 요소 노드를 생성
    const $newChild = document.createElement('li');
    $newChild.textContent = 'Banana';
    
    // #fruits 요소 노드의 첫 번째 자식 요소 노드를 $newChild 요소 노드로 교체
    $fruits.replaceChild($newChild, $fruits.firstElementChild);
  </script>
</html>
// innerHTML
// 요소 노드의 content 영역(테그 시작 ~ 데그 종료 사이) 내에 포함된 
// 모든 HTML 마크업을 문자열로 반환한다.
const oneDiv = document.createElement('div');  // oneDiv 변수에 <div> tag를 생성한다.
oneDiv.classList('hi');                        // <div class="hi"></div>
oneDiv.textContent('hello ');                   // <div class="hi">hello </div>

const oneSpan = document.createElement('span');  // oneSapn 변수에 <span> tag를 생성한다.
oneSpan.textContent('world!');                   // <span>world!</span>
oneDiv.append(oneSpan);                // <div class="hi">hello <span>world!</span></div>

console.log(document.querySelect('.hi').innerHTML);
// "hello <span>world!</span>
<!-- innerHTML 단점 1 -->
<!-- 크로스 사이트 스크립팅 공격에 취약하다. 1 -->
<!DOCTYPE html>
<html>
  <body>
    <ul id="fruits">
      <li class="apple">Apple</li>
    </ul>
  <body>
  <script>
    const $fruits = document.getElementById('fruits');
    
    // 노드 추가
    $fruits.innerHTML += '<li class="banana">Banana</li>;
    
    // 노드 교체
    $fruits.innerHTML = '<li class="banana">Banana</li>;
    
    // 노드 삭제
    $fruits.innerHTML += ';
  </script>
</html>

<!-- innerHTML 프로퍼티를 사용한 DOM 조작은 구현이 간단하고 직관적이라는 장점이 있지만 -->
<!-- 이렇게 사용자로 부터 입력받은 데이터를 그대로 innerHTML 프로퍼티에 할당하는 것은 -->
<!-- 크로스 사이트 스크립팅 공격(XSS: Cross-Side Scripting Attacks)에 취약하므로 위험하다. -->


<!-- 크로스 사이트 스크립팅 공격에 취약하다. 2 -->
<!DOCTYPE html>
<html>
  <body>
    <div id="foo">Hello</div>
  <body>
  <script>
    // innerHTML 프로퍼티로 스크립트 태그를 삽입하여 자바스크립트가 실행되도록 한다.
    // HTML5는 innerHTML 프로퍼티로 삽입된 script 요소 내의 자바스크립트 코드를 실행하지 않는다.
    document.getElementById('foo').innerHTML = '<script>alert(document.cookie)</script>';
    
    // 에러 이벤트를 강제로 발생시켜서 자바스크립트 코드가 실행되도록 한다.
    document.getElementById('foo').innerHTML = '<img src="x" onerror="alert(document.cookie)">';
  </script>
</html>
<!-- innerHTML 단점 2 -->
<!-- 모든 자식 노드를 제거하고 할당한 HTML 마크업 문자열을 파싱하여 DOM을 변경해서 비효율적이다. -->
<!DOCTYPE html>
<html>
  <body>
    <ul id = "fruits">
      <li class ="apple">Apple</li>
    </ul>
  <body>
  <script>
    const $fruits = document.getElementById('fruits');
    
    // 노드 추가
    $fruits.innerHTML += '<li class="banana">Banana</li>';
    // '<li class="apple">Apple</li>' + '<li class="banana">Banana</li>'
  </script>
</html>

<!-- #fruits 요소의 모든 자식 노드(li.apple)를 제거하고 -->
<!-- 새롭게 요소 노드 li.apple과 li.banana를 생성하여 #fruits 요소의 자식 요소로 추가한다. -->
<!-- innerHTML 단점 3 -->
<!-- 새로운 요소 삽입 위치를 지정할 수 없다. -->
<!DOCTYPE html>
<html>
  <body>
    <ul id = "fruits">
      <li class="apple">Apple</li>
      <li class="orange">Orange</li>
    </ul>
  <body>
</html>

<!-- li.apple 요소와 li.orange 요소 사이에 새로운 요소를 삽입하고 싶은 경우 -->
<!-- innerHTML 프로퍼티를 사용하면 삽입 위치를 지정할 수 없다. -->
<!-- innerHTML 프로퍼티를 사용한다면 기존요소를 제거하지 않으면 삽입할 수 없다. -->
<!-- insertAdjacentHTML(position, DOMString) -->
<!-- 기존 요소를 제거하지 않으면서 위치를 지정해 새로운 요소를 삽입한다. -->
<!-- 두 번째 인수로 전달한 HTML 마크업 문자열(DOMString)을 파싱하고 --> 
<!-- 그 결과로 생성된 노드를 첫 번째 인수로 전달한 위치(position)에 삽입하여 DOM에 반영한다. -->

<!DOCTYPE html>
<html>
  <body>
    <!-- beforBegin -->
    <div id='foo'>
      <!-- afterBegin -->
      text
      <!-- beforEend -->
    </div>
    <!-- afterEnd -->
  <body>
  <script>
    const $foo = document.getElementById('foo');
    
    $foo.insertAdjacentHTML('beforeBegin','<p>beforeBegin</p>');
    $foo.insertAdjacentHTML('afterBegin','<p>afterBegin</p>');
    $foo.insertAdjacentHTML('beforeEnd','<p>beforeEnd</p>');
    $foo.insertAdjacentHTML('afterEnd','<p>afterEnd</p>');
  </script>
</html>

<!-- innerHTML 프로퍼티보다 효율적이고 빠르다. -->
<!-- 단, innerHTML 프로퍼티와 마찬가지로 insertAdjacentHTML 메서드는  -->
<!-- HTML 마크업 문자열을 파싱하므로 크로스 사이트 스크립팅 공격에 취약하다. -->

삭제 (Delete)

const oneDiv = document.createElement('div');  // oneDiv 변수에 <div> tag를 생성한다.
oneDiv.textContent = 'hello';                  // text를 변수에 추가한다.
console.log(oneDiv);                           // <div>hello</div>

// 방법 1
// remove
oneDiv.remove();                          // oneDiv를 전부 삭제한다.

// 방법 2
// removeChild(child)
while(container.firstChild){              // container에 첫 번째 자식이 없을 때까지 삭제한다.
	container.removeChild(container.firstChild);
}

// 방법 3
while (container.children.length > 1) {  // container의 자식이 하나 남을 때까지 삭제한다.
	container.removeChild(container.lastChild);
}

// 방법 4
const greeting = document.querySelectorAll('.hi');
greeting.forEach(function(hi){  
	greeting.remove();                   // class 이름이 hi인 모든 요소를 삭제한다.
})

// 방법 5
const greeting = document.querySelectorAll('.hi');
for (let hi of greeting){     
	hi.remove()                          // class 이름이 hi인 모든 요소를 삭제한다.
}

적용 (Append)

const oneDiv = document.createElement('div');  // oneDiv 변수에 <div> tag를 생성한다.
oneDiv.textContent = 'hello';                  // text를 변수에 추가한다.
console.log(oneDiv);                           // <div>hello</div>

// append
container.append(oneDiv);      // container에 변수 oneDiv를 적용시킨다.
document.body.append(oneDiv);  // body에 변수 oneDiv를 적용시킨다.

// appendChild
container.appendChild(oneDiv);  // container에 변수 oneDiv를 마지막 자식 요소로 추가한다.

 

 

DOM (2)을 알아보는 시간이었습니다.
틀린 내용은 댓글로 알려주시면 감사하겠습니다.

 
 

반응형
profile

Space

@Space_zero

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!