Programming/Java Script

[K-MOOC x Coursera ] JavaScript Basic - Module 3 : DOM

감귤밭호지차 2022. 11. 11. 17:57

DOM : Document Object Model  - 문서 객체 모델 

>> 문서 객체 :  <html> 이나 <body>같은 html문서의 태그들을 JS가 이용할 수 있는 객체로 만드는 것을 의미한다. 

>> Model : 모듈이라고 인식하면 되는데 여기서는 문서 객체를 " 인식하는 방법" 이라고 이해하면 된다. 

 

 ∴ DOM은  웹 브라우저가 HTML 페이지를 JS가 이용할 수 있는 객체로 만들어서 "인식" 하는 방식 

                     or 문서 객체와 관련된 객체의 집합을 의미 


WebPage도 객체이다. 

각각의 네모 칸은 node(노드)

 

이러한 형태의 자료구조를 tree 형 자료구조라고 한다.

Window 는 부모 노드 

맨 마지막 요소들은 root(뿌리) 노드

 


 

 

HTML 태그 : 요소 노드 

요소 노드 안의 글자 : text 노드 

 

HTML 태그 뿐만이 아니라 그 안의 텍스트속성 또한 " 노드 "이다. 

 

 

 

참고 블로그 : 링크-감사합니다.


노드 (Node) 

NodeA.firstChild = Node-A1

NodeA.lastChild = Node-A3

NodeA.ChildNodes.length = 3

NodeA.childNodes[0] = Node-A1

NodeA.childNodes[1] = Node-A2

NodeA.childNodes[2] = Node-A3

Node-A1.parentNode = NodeA

Node-A1.nextSibling = Node-A2

Node-A3.prevSibiling = Node-A2

Node-A3.nextSibling = null

Node-A.lastChild.firstChild = Node-A3-A

Node-A3-A.parentNode.parentNode = NodeA

 

-


■  Dot Syntax & Methods 

우리는 dot.period(  .  )를 객체를 속성이나 함수로부터 분리할 때 사용하곤 한다. 

몇까지 유용한 document method에 대해서 알아보자 

 

>> getElemtnById()

 : 문서 객체로 엄밀히 말하자면 함수인데 문서 객체에 속해있는 함수라고 생각하면 된다. 

   이 함수는 해당 요소로 이동해서 그 특정 요소 id 를 찾는다. 

 

//getElemtnById(); 사용법
<body>
  <p id = "one" > Here is some text </p>
  <script>
	document.getElementById("one").style.color = "red";
  </script>
</body>

 

>> getElemtnsByTagName()

 : 특정 요소를 가지고 있는 tag 들을 모을 수 있다. 

 

예시로 getElementsTagName를 이용해서 특정 요소의 tag들을 하나로 모아보자!

//getElementsById(); 사용법
<body>
  <h1>DOM Examples</h1>
  <p>Here is a paragraph</p>
  <p>Here is another paragraph</p>
  <p>Here is one more paragraph</p>
  <script>
    var myParagraphs = document.getElementsByTagName('p');
    console.log(myParagraphs);  // 출력 : HTMLCollection(3) [ p, p, p]
  </script>
</body>

 

위의 함수에다가 loop문을 적용해서  해당 특정 요소들의 속성에 변경을 줄 수 있다.

** alert()을 이용해서 i변수의 값을 확인해보자 (firefox - chrome은 적절하게 안 보여 줌)

<script>
  var myText = document.getElementsByTagName("p");
  for( var i = 0; i < myText.length; i++) {
    myText[i].style.color = "red";
    alert(`this is element ${i}`);
  }
</script>

 

>>  getElementsByClassName();

//getElementsByClassName(); 사용법
<body>
  <h1>DOM Examples</h1>
  <p class ="special" >Here is a paragraph</p>
  <p>Here is another paragraph</p>
  <p class ="special" >Here is one more paragraph</p>
  <script>
    var myClass = document.getElementsByClassName('special');
    
    for( var i = 0; i < myClass.length; i++) {
      myClass[i].style.color = "red";
    }
  </script>
</body>

getElementsByClassName 이나 getElementsByTagName과 같은 요소들을 collection 하는 기능/함수를 사용할 경우 우리는 이것을 collection 처럼 다루어야 한다. 설사 요소가 하나뿐이거나 아예 없더라도 Java Script는 collection 요소에 접근/가져온다. 

 


[ 들어가기 전에 ... ]

2009년에 ES5가 사실상 웹용 스크립팅의 표준이 되었다. 하지만 jQuery라고 불리우는 라이브러리의 등장이 있었다. 그 당시에 jQuery 라이브러리는 어마어마한 인기를 얻었고 지금은 그만큼은 아니지만 DOM에서 요소를 가져오고 이를 사용하여 작업을 훨씬 쉽게 할 수 있었기 때문에 엄청난 인기를 가졌었다. 그리고 이러한 인기와 이유 때문에 JS는 2013년에 ES6 이전에 이 기능을 추가했고 이는 querySelector과 querySelectorAll을 사용하게 해주는 API 이다. 위에서 설명한 메서드 들과는 약간은 작동 방법이 다르다. 

 

>>  querySelector();

이러한 메소드의 도입으로 인해 우리는 jQuer가. 예전만큼 필요하지는 않게 되었다. 이 문서 객체의 함수는 query,의 첫번째 매치 값을 return 해 줄 것이다. ( The document method querySelector(); will return the first match of a query)

 

//querySelector( ); 사용법
<body>
  <h1>DOM Examples</h1>
  <div id = "special">
    <p class ="someclass" >Here is a paragraph</p>  // 첫번째 match라서 red로 변환
    <p>Here is another paragraph</p>
    <p class ="someclass" >Here is one more paragraph</p>  //red변환 안됨
  </div>
  <script>
    var mText = document.querySelector(`#speical .someclass`);
    myText.style.color ="red";
  </script>
</body>

출력 화면

 

>>querySelectorAll( );

This document method will get all the elements that match a certain selector. It returns a nodeList of elements that you have to loop through.(해당하는 모든 요소들을 가져오고 반복해야 하는 노드 리스트를 반환한다.)

 

//querySelectorAll( ); 사용법
<body>
  <h1>DOM Examples</h1>
  <div id = "special">
    <p>Here is a paragraph</p> 
    <p>Here is another paragraph</p>
    <p>Here is one more paragraph</p>
  </div>
  <script>
    var mText = document.querySelectorAll(`#speical p`);
    for( var i = 0; i < myText.length; i++) {
      myText[i].style.color = "red";
    }
  </script>
</body>

출력 화면


Working with Properties  (* Properties들은 괄호 사용하지 않음)

 ▷ element.style.color = "color name ";

 ▷ .style.property = "value";

 ▷ .innerHTML = "value";

 ▷ .className = "value";

 

Working with Element Methods

 ▷ .setAttribute("attributeName", "value");

 ▷ .removeAttribute("attributeName");

 ▷ .getAttribute("attributeName");

 

 

 


■ InnerHTML

Using the innerHTML property can be very powerful.  

"InnerHTML"속성은 요소의 HTML 콘텐츠 를 설정하거나 변환시킨다. -W3S

 

<body>
 <div id="special">
   <p>Here is some text</p>
   <p>Here is some more text</p>
 </div>
 
 <scipt>
   var myDiv = document.getElementById('special');    // querySelector 동일하게 적용 
   myDiv.innerHTML = "<p>I love cheese</P>"
 //document.querySelector('#special').innerHTML = "<p>I love cheese</p>";    이렇게 작성 가능
 </scipt>
</body>

이렇게 되면 원래의 <script>적용 전 화면은 <body>태그 안의 내용들이 나타나지만 <script>의 innerHTML로 인하여 모든 문장들이 사라지고 (div - speical안의 모든 문장들) " I love cheese " 만 화면에 출력되게 된다. 

 

 

다른 예시를 보면 myP - id 속성의 " I am a paragraph"가 ".innerHTML" 기능을 통해 demo - id 속성의 <p> 태그 안에 적용된 것을 볼 수가 깄다. 

 

 

ClassName

Setting the ClassName property allows you to set the class, or classes for an element.

<head>
  <meta charset=UTF-8>
  <meta name ="viewpoint" content ="width=device-width,initial-scale=1.0">
  <title>DOM Examples</title>
  <style>
    .blue { color: blue; }
  </style>
</head>
<body>
 <div id="special">
   <p>Here is a paragraph</p>         //파란색 변환 classs="blue" 생성됨 
   <p>Here is another paragraph</p>
   <p>Here is one more paragraph</p>
</div>
 
 <scipt>
   var firstPara = document.querySelector('p');
   firstParal.className = "blue";
 </scipt>
</body>

className은 style 보다 강력한 영향을 가지고 있기 때문에 두가지가 동시에 속성을 가지고 있다면 className에 다양한 종류의 작업을 선언 할 수 있다.  class이름의 속성을 이용하여 이미 페이지에 존재해있는 class를 설정할 수 있어 굉장히 유용하다. ( This is a super useful, using the class name property to set a class that already exists on the pages.)  

첫 번째 문단에 class blue가 선언되었다.

 

>> setAttribute();

This method let's you set any type of attribute on an element.

<body>
  <h1></h1>
  <form>
    <label><input type="checkbox"> YES! </label>
  </form>
  <sciprt>
    var myCheckbox = document.querySelector('input');
    myCheckbox.setAttribute('checked', 'checked');
    </script>
</body>

새로고침을 해도 기본 default값이 checked여서 계속 checked되어진다. 이 함수는 여러 속성(attribue)에 사용할 수 있다. 접근할 수 있는 모든 속성을 setAttribute에서 사용 해서 원하는 값으로 설정 할 수 있다.

더보기

Q. Suppose you want JacaScript to dynamically add content to a web page, which methods or properties could be used to achieve this?

 

1. The inner HTML property 

    : This is a property that will allow you to add content inside a provided element.

2. The document createElement and createTextNode methods, combined with the document appendChild method.

: These two methods will allow you to create new elements and add them to the page. 

 


Creating Elements and Text Nodes : 요소 추가

Easy to add HTML to a page using innerHTML.  but sometimes we need to actually create an element. Put some text in it, and add it to the page.

 

>> createElement( ' 태그 요소 '); >> createTextNode(" 문자열 ?? " );

▧ 나는 저렇게 결과가 나오지 않음... 왜지..? 

"Here is a new paragrpah" 가 나오지 않음..? 왜지????/

 

예시의 appendChild메소드는 JavaScript에서 부모 노드에 자식 노드를 추가하는 메서드입니다. 

- appendChild( ); 
오직 노드 객체만 가능하며 한번에 하나의 노드만 추가할 수 있습니다. return 값을 반환합니다. 

- append( );
노드 객체와 DOM String(text) 사용이 가능하며 한번에 여러 개의 자식 요소를 설정 할 수 있습니다. 
return 값을 반환 하지 않습니다. 
// Node object 
const parent = document.createElement('div');
const child = document.createElement('p');

parent.append(child); 

/** 결과 : 
<div>
  <p></p>
</div>
*/   

// DOM String
const parent = document.createElement('div');
parent.append('예시문구 입니다.');

/** 결과 : 
<div>
  예시 문구 입니다. 
</div>
*/

//여러 개의 자식 요소 설정 
const div = document.createElement('div');
const span = document.createElemnt('span');
const p = documsnt.createElememtn('p');

document.body.append(div, "hello", span, p); //body 안에 ( ) 안의 요소들이 자식으로 주르륵

/** 결과 : 
<body>
  <div></div>
  hello
  <span></span>
  <p></p>
</body>
*/

 

 

Removing Elements

 

 

요소를 삭제하는 방법에는 여러가지가 있지만 가장 기본적인 메소드인 "removeChild( ); "메소드를 소개하겠습니다. 

 

아래의 예제를 보면 <p>문단 2개가 출력되었습니다. 두 번째 <p>를 삭제하기 위해 주석 처리한 removeChild();메소드를 다시 활성화 시키면 두번째 <p>문단은 제거가 됩니다. 

 

- 제거된 두 번째 문장.

 

 


우리는 DOM에 접근할 수 있는 몇 개의 메소드를 알아보았습니다. 이 메소드말고도 더 많은 메소드들이 존재하지만 지금으로써는 충분할 겁니다. (ㅋㅋㅋㅋ) 다른 언어를 사용하다가 JS에 와서 이 메소드들을 본다면 굉장히 이상하다고 느낄 수도 있지만 자바스크립트의 브라우저와 긴밀한 통합이 프로그래밍 언어로서의 존재 이유입니다.(/?)

 

JS는 페이지를 tree 객체로서 봅니다. 우리는 해당 문서를 탐색하고 요소를 찾은 후 다양한 메서드와 속성을 사용해서 영향을 끼칠 수 있습니다. 

 

다음 수업 목차는 Capturing Events with JavaScript 입니다. 링크를 따라 가세요. 

 

 

 

Thanks to ...

  참고 : W3S

  참고 : 블로그