1. window 객체

window 객체는 브라우저 창을 대변하면서 자바스크립트에서 최상단에 존재하는 객체이다.
자바스크립트 코드 어느 곳에서나 항상 접근할 수 있는 객체이기 때문에 전역 객체, Global Object라고 부르고,
어떤 프로퍼티나 메소드를 사용하든 결국 전역 객체 내부의 것이기 때문에 앞에 window.을 생략할 수도 있다.

window.console.log(window);
window.console.log(window.innerWidth);
window.console.log(window.innerHeight);

2. DOM (Document Object Model, 문서 객체 모델)

간단하게 표현하면 웹 페이지(웹 문서)에 나타나는 HTML 문서 전체를 객체로 표현한 것으로 생각하면 되는데, 이때 각 객체를 노드(Node)라는 용어로 표현하고, 태그는 요소 노드, 문자는 텍스트 노드로 구분된다.

console.log(document);

출력되는 화면, DOM을 직접적으로 접근하게 되면 객체가 아니라 DOM에 해당하는 HTML이 출력된다.

자바스크립트에서 사용해봤던 document 객체가 이 웹 문서의 최상단 객체로 진입점의 역할을 한다.
그래서 document 객체를 활용하면 웹 페이지 내부에 무엇이든 수정할 수 있고, 새로운 콘텐츠를 만들 수도 있다.

3. DOM 트리

DOM 트리

HTML의 계층 구조는 DOM에서도 반영되는데 이러한 계층구조를 나무에 비유해서 DOM 트리라고 부른다.
각 노드 간의 관계는 부모, 자식, 형제라는 용어로 표현한다. DOM 트리의 구조를 잘 파악하고 필요한 노드에 좀 더 자유롭게 접근하기 위해서는 관계(부모, 자식, 형제)를 잘 이해하는것이 중요하다.

태그를 표현하는 노드를 요소 노드(Element Node)라고 부르고, 문자를 표현하는 노드를 텍스트 노트(Text Node)라고 부른다. 일반적으로 텍스트 노드들은 요소 노드의 자식 노드가 되고, 따로 자식 노드를 가질 수 없기 때문에 나무의 잎사귀에 비유해서 잎 노드(Leaf Node)라고 한다. 

4. DOM 이동 시 활용 가능한 프로퍼티

프로퍼티 유형 결과
element.children 자식 요소 노드 element의 자식 요소 모음(HTMLCollection)
element.firstElementChild 자식 요소 노드 element의 첫 번째 자식 요소 하나
element.lastElementChild 자식 요소 노드 element의 마지막 자식 요소 하나
element.parentElement 부모 요소 노드 element의 부모 요소 하나
element.previousElementSibling 형제 요소 노드 element의 이전(previous) 혹은 좌측(left)에 있는 요소 하나
element.nextElementSibling 형제 요소 노드 element의 다음(next) 혹은 우측(right)에 있는 요소 하나
node.childNodes 자식 노드 node의 자식 노드 모음(NodeList)
node.firstChild 자식 노드 node의 첫 번째 자식 노드 하나
node.lastChild 자식 노드 node의 마지막 자식 노드 하나
node.parentNode 부모 노드 node의 부모 요소 하나
node.previousSibling 형제 노드 node의 이전(previous) 혹은 좌측(left)에 있는 노드 하나
node.nextSibling 형제 노드 node의 다음(next) 혹은 우측(right)에 있는 노드 하나

요소 노드에 대한 이동 프로퍼티  /  모든 노드에 대한 이동 프로퍼티

<body>
  <div id="content">
    <h2 id="title-1">Cat-1</h2>
    <ul id="list-1">
      <li></li>
      <li></li>
      <li></li>
    </ul>
    <h2 id="title-2">Cat-2</h2>
    <ul id="list-2">
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ul>
  </div>
  <script src="index.js"></script>
</body>
//DOM 트리 여행하기
const myTag = document.querySelector('#content');

console.log(myTag);

//자식 요소 노드
console.log(myTag.children); 
console.log(myTag.children[1]);  //자식 요소 노드의 1번째 인덱스에 오는 요소. list-1
console.log(myTag.firstElementChild);  //첫번째 자식 요소. title-1
console.log(myTag.lastElementChild);  //마지막 자식 요소. list-2

//부모 요소 노드
console.log(myTag.parentElement); //body태그가 선택된다.

//형제 요소 노드
console.log(myTag.previousElementSibling); //이전, 좌측에 있는 형제. null
console.log(myTag.nextElementSibling); //다음, 우측에 있는 형제. script

5. 주요 요소 노드 프로퍼티

프로퍼티 내용 참고사항
element.innerHTML 요소 노드 내부의 HTML코드 문자열로 리턴
(줄바꿈이나 들여쓰기, 띄어쓰기도 모두 포함)
요소 안의 정보를 확인할 수도 있지만, 내부의 HTML 자체를 수정할 때 좀 더 자주 활용
element.outerHTML 요소 노드 자체의 전체적인 HTML 코드를 문자열로 리턴 (해당요소 포함)
(줄바꿈이나 들여쓰기, 띄어쓰기도 모두 포함)
outerHTML은 새로운 값을 할당하면 요소 자체가 교체되어 버리기 때문에 주의 (수정X 처음 선택한 요소는 사라진다.)
element.textContent 요소 노드 내부의 내용들 중에서 HTML을 제외하고 텍스트만 리턴 textContent는 말그대로 텍스트만 다루기 때문에 HTML태그를 쓰더라도 모두 텍스트로 처리됨
<body>
  <div id="content">
    <h2 id="title-1">Cat-1</h2>
    <ul id="list-1">
      <li>wonderful</li>
      <li>beautiful</li>
      <li>great</li>
    </ul>
    <h2 id="title-2">Cat-2</h2>
    <ul id="list-2">
      <li>dog</li>
      <li>cat</li>
      <li>monkey</li>
      <li>pig</li>
    </ul>
  </div>
  <script src="index.js"></script>
</body>
//요소 노드 주요 프로퍼티
const myTag = document.querySelector('#list-1');

//innerHTML
console.log(myTag.innerHTML);
myTag.innerHTML = '<li>Exotic</li>';
myTag.innerHTML += '<li>Exotic</li>'; //덧셈 할당 연산자를 통해 기존 HTML 마지막 부분에 추가할 수도 있다.

//outerHTML
console.log(myTag.outerHTML);
myTag.outerHTML = '<ul id="new-list"><li>Exotic</li></ul>';
//수정이 아닌 교체. 처음 선택한 요소는 사라지고 새로 HTML을 만드는 것이다.

//textContext
console.log(myTag.textContext);
myTag.textContext = 'new text!';
//새로운 값을 할당하면 innerHTML과 마찬가지로 내부의 값을 완전히 새로운 값으로 교체

innerHTML 수정 전(좌)과 수정 후(우)

6. 요소 노드 다루기

1. 요소 노드 만들기: document.createElement('태그이름')
2. 요소 노드 꾸미기: element.textContent, element.innerHTML, ...
3. 요소 노드 추가 혹은 이동하기: element.prepend, element.append, element.after, element.before
4. 요소 노드 삭제하기: element.remove()

<body>
  <div>
    <h1>오늘 할 일</h1>
	<ol id="today">
	  <li>자바스크립트 공부</li>
	  <li>고양이 화장실 청소</li>
	  <li>고양이 장난감 쇼핑</li>
	</ol>
	<h1>내일 할 일</h1>
	<ol id="tomorrow">
	  <li>자바스크립트 공부</li>
	  <li>뮤지컬 공연 예매</li>
	  <li>유튜브 시청</li>
	</ol>
  </div>
  <script src="index.js"></script>
</body>
// 요소 노드 추가하기
const tomorrow = document.querySelector('#tomorrow');

// 1. 요소 노드 만들기: document.createElement('태그이름')
const first = document.createElement('li');

// 2. 요소 노드 꾸미기: textContent, innerHTML, ...
first.textContent = '처음';

// 3. 요소 노드 추가하기: NODE.prepend, append, after, before
tomorrow.prepend(first);

const last = document.createElement('li');
last.textContent = '마지막';
tomorrow.append(last);

const last = document.createElement('p');
prev.textContent = '이전';
tomorrow.before('문자열');

const last = document.createElement('p');
next.textContent = '다음';
tomorrow.after(next);
// 노드 삭제와 이동
const today = document.querySelector('#today');
const tomorrow = document.querySelector('#tomorrow');

// 노드 삭제하기: Node.remove()
tomorrow.remove();
today.children[2].remove();

// 노드 이동하기: prepend, append, before, after
today.append(tomorrow.children[1]);
//today에 tomorrow의 1번째 인덱스 자식요소를 가져와줘 (today의 맨마지막에 추가된다.)
tomorrow.children[1].after(today.children[1]);
//tomorrow에 자식요소 1번째 인덱스 뒤에 today 자식요소 1번째 인덱스를 옮겨줘
tomorrow.children[2].before(today.children[1]);
//tomorrow의 자식요소 2번째 인덱스 앞에 today 자식요소 1번째 인덱스를 옮겨줘 
tomorrow.lastElementChild.before(today.children[1]);
//tomorrow의 마지막 자식 요소의 앞에 today 자식요소 1번째 인덱스 가져와줘

7. HTML 속성 다루기

대부분의 HTML 속성은 DOM 객체의 프로퍼티로 변환이 된다. 하지만, 표준 속성이 아닌 경우에는 프로퍼티로 변환이 안 되는데, 아래 메소드를 활용하면 표준이 아닌 HTML 속성들도 다룰 수 있다.

1. 속성에 접근하기: element.getAttribute('속성')
2. 속성 추가(수정)하기: element.setAttribute('속성', '값')
3. 속성 제거하기: element.removeAttribute('속성')

// HTML 속성 (HTML attribute)
const tomorrow = document.querySelector('#tomorrow');
const item = tomorrow.firstElementChild;
const link = item.firstElementChild;

// elem.getAttribute('속성'): 속성에 접근하기
console.log(tomorrow.getAttribute('href'));
console.log(item.getAttribute('class')); //getAttribute를 활용할 때는 class라는 문자열을 그대로 전달

// elem.setAttribute('속성', '값'): 속성 추가(수정)하기
tomorrow.setAttribute('class', 'list'); // 추가
link.setAttribute('href', 'https://www.codeit.kr'); // 수정

// elem.removeAttribute('속성'): 속성 제거하기
tomorrow.removeAttribute('href'); 
tomorrow.removeAttribute('class');

// id 속성
console.log(tomorrow);
console.log(tomorrow.id);

// class 속성
console.log(item);
console.log(item.className); //프로퍼티 이름으로 접근할때는 className이지만

// href 속성
console.log(link);
console.log(link.href);
console.log(tomorrow.href);

8. 스타일 다루기

자바스크립트로 태그의 스타일을 다루는 방법에는 크게 두 가지가 있다.

1. style 프로퍼티 활용하기: element.style.styleName = 'value';
2. class 변경을 통해 간접적으로 스타일 적용하기: element.className, element.classList

‼️style 프로퍼티를 통해서 css 속성을 다룰 때 여러 단어를 이어서 만든 속성은 카멜 표기법을 사용해야한다.

// 스타일 다루기
const today = document.querySelector('#today');
const tomorrow = document.querySelector('#tomorrow');

// style 프로퍼티
today.children[0].style.textDecoration = 'line-through';
today.children[0].style.backgroundColor = '#DDDDDD';
today.children[2].style.textDecoration = 'line-through';
today.children[2].style.backgroundColor = '#DDDDDD';

style 프로퍼티를 활용하면 태그에 직접적으로 적용되어 버리기 때문에 스타일 우선순위가 높아진다는 문제가 있다.
그래서 style 프로퍼티를 사용하는 것보다 태그의 클래스를 변경하는 방식이 조금 더 권장되는 방식이다.

css에 미리 스타일을 지정해두고,

.done {
  opacity: 0.5;
  text-decoration: line-through;
}
// elem.className
today.children[1].className = 'done';

className 프로퍼티에 새로운 값을 할당해서 코드를 실행해보면, done 클래스에 미리 작성해둔 스타일이 입혀지는 방식인 것이다. 다만 한가지 문제는 className 프로퍼티로 값을 변경하게 되면 클래스 속성 값 전체가 바뀌게 된다. 기존에 있던 class는 사라지고 새로 부여한 class만 남는다는 뜻!

하지만 상황에 따라서 기존에 class는 그대로 둔 채로 새로 추가 하고 싶을 수도 있을 것이다. 그럴 때는 classList를 사용하면 된다.

// elem.classList
console.log(today.classList);
console.log(today.children[1].classList);

// elem.classList: add, remove, toggle
const item = tomorrow.children[1];
item.classList.add('done'); //추가
item.classList.remove('done'); //삭제
item.classList.toggle('done'); //있으면 제거, 없으면 추가

//add와 remove는 여러개의 파라미터 값을 줄 수 있다.
item.classList.add('done', 'other');

//toggle은 여러개의 파라미터는 줄 수 없고, 두번 째 파라미터가 boolean형태의 값을 전달 받아서 
//true일 땐 add의 기능만, fales일 땐 remove의 기능만하도록 toggle의 기능을 강제하는 역할을 한다.
item.classList.toggle('done', false);

classList는 클래스의 속성 값을 유사배열로 다루는 프로퍼티이다. 클래스 속성을 하나씩 다룰 수 있는 것 뿐만 아니라 add, remove, toggle이라는 메소드도 활용할 수 있다.

위 코드의 classList 출력(consol.log)값

메소드 내용 참고사항
classList.add 클래스 추가하기 여러 개의 값을 전달하면 여러 클래스 추가 가능
classList.remove 클래스 삭제하기 여러 개의 값을 전달하면 여러 클래스 삭제 가능
classList.toggle 클래스 없으면 추가, 있으면 삭제하기 하나의 값만 적용 가능하고, 두 번째 파라미터로 추가 또는 삭제 기능을 강제할 수 있음

'코린이 개념잡기 > JavaScript' 카테고리의 다른 글

자바스크립트 이벤트  (0) 2024.12.14
console.log와 console.dir의 차이  (0) 2024.12.13
이벤트와 클릭  (0) 2024.12.13
태그 선택하기  (0) 2024.12.12
조건문  (0) 2024.01.20

+ Recent posts