S1 Unit 11. DOM

나현·2022년 9월 13일
0

학습일지

목록 보기
13/53
post-thumbnail

💡 이번에 배운 내용

  • Section1.
    웹 프론트엔드 개발의 기초지식을 기반으로 스스로 단순한 Web App을 만들 수 있다.
  • Unit11. DOM : DOM의 개념을 학습하고 Javascript로 HTML요소를 조작할 수 있다.

느낀점

전체적인 개념은 쉽게 익힐 수 있었지만 이벤트는 막상 실습해보니 좀 더 연습이 필요했다. 실습을 많이 해봐야 겠다. 이벤트를 다루는 길은 쉽지 않다.
이번의 과제는 유효성 검사 기능을 만들어 보는 과제였는데, 다행히 과제는 바로 일찍 끝낼 수 있었다.
하지만 추가로 공부해야 할 것들이 많았다! 이번 포스트에 정리한 내용 자체는 많지 않았지만, 검색해보고 여러 자료를 읽어보는 게 시간이 은근 걸렸다. 이 많은걸 어떻게 정리해야 하나 생각하면서 포스트 작성도 시간이 좀 걸렸다. 추석 후라 불타올랐던 공부 의지가 조금 꺾인 것도 한 몫 한듯 하다.
학습이 조금 더뎠지만 그래도 이번에도 무사히 학습을 마쳤다. 오늘도 많이 배웠다!


키워드

DOM, document, console.dir, CRUD, createElement, querySelector, append, 이벤트, 이벤트 객체, addEventListener, onclick


학습내용

DOM(Document Object Model)은 HTML요소를 Javascript의 객체처럼 조작할 수 있는 모델이다. DOM은 각 요소 간의 관계가 트리구조로 되어 있다.

참고: javascript MDN - DOM

Ch1. HTML에 javascript 적용하기

script 요소의 실행 시점

HTML 웹문서에 자바스크립트를 불러오려면 script태그로 작성한다. 브라우저는 웹 문서를 해석하다 script 요소를 발견했을 때 그 내용을 먼저 실행한다.
때문에 HTML요소를 조작하려면 조작하려는 HTML이 다 불러온 시점에 script태그를 작성해야 한다.
그래서 보통 body의 닫는태그 직전에 script태그를 작성한다.

<body>
<!-- HTML 내용 생략-->
<sciprt src="index.js"></script>
</body>

document 객체

HTML 요소는 javascript에서 document 객체에 저장되어 있다.
DOM구조를 조회할 때는 console.dir(document.조회하고자 하는 요소);를 사용하면 해당 요소의 속성도 함께 확인해 볼 수 있다.
DOM을 사용하기 위해서 HTML의 구조(특히 자식, 부모 요소)를 잘 알아야한다.
HTML의 구조는 트리구조로 되어 있으며 부모 요소, 자식 요소가 존재한다.
부모요소와 자식요소는 아래와 같은 명령어를 통해 확인할 수 있으며
요소가 여러 개일 경우 유사배열형태로 인덱스가 존재함을 확인할 수 있다.

<body>
  <div id="content"></div>
</body>
//유사 배열 형태로 자식 요소를 확인할 수 있다.
console.log(document.body.children);

//body의 자식 중 0번째 요소. 위의 예제에서는 #content
//console.dir를 사용하면 요소의 속성을 자세히 살펴볼 수 있다.
console.dir(document.body.children[0]);

//위와 같이 변수에 할당도 가능하다.
let content=document.body.children[0];

//html요소인 부모 요소를 확인할 수 있다.
console.log(document.content.parentElment);

Ch2. DOM 다루기

javascript를 이용해 DOM을 CRUD(Create, Read, Update, Delete)하고 append(적용)할 수 있다.

//create
const menu=document.createElement('div');

//read
const content=document.querySelect('#content');

//append
content.append(menu);

//update
//클래스명 추가
menu.classList.add('menu');
//텍스트 적용
menu.textContent='마이메뉴';
//그 외 속성 지정은 setAttribute

//delete
menu.remove();

create

요소를 생성할 때는 document.createElement(요소); 구문을 사용해 생성한다.
요소는 문자열로 입력하며 생성한 요소는 append하지 않으면 실제 HTML구조에 적용되지 않는다.

read

요소를 읽어오거나 검색할 때는 주로 document.querySelector(); 를 사용한다.
이외에도 아래와 같은 방법으로 읽어올 수 있다.

//해당 HTML요소가 여러 개일 경우 그 중 첫번째 요소를 불러온다.
//요소 안은 CSS와 같은 선택자를 사용한다.
const contentQuery=document.querySelector('#content');

//해당 HTML요소가 여러 개일 경우 모든 요소를 불러온다. 유사 배열 형태이다.
const menus=document.querySelectorAll('.menu');

//id를 이용해 HTML요소를 불러오는 방법으로 예전 방식이다. 만약 브라우저 호환성 이슈가 있을 때 사용한다.
const contentGet=document.getElementById('content');

참고: javascript MDN - querySelector

append

생성한 요소를 원하는 HTML 자리에 적용하거나 삽입할 때 사용한다.
원하는 자리를 read와 관련된 구문을 사용하여 불러오고, create 관련 구문으로 생성했으면 append하여 실제 HTML구조에 적용해야 한다.
원래 있던 요소를 삽입하면 이동이 된다.

  • 부모 노드.append(생성한 요소);
    '부무 노드'의 마지막 자식 노드로 생성한 요소를 삽입할 수 있다.
  • 부모 노드.appendChild(자식 노드)
    '부모 노드'의 마지막 자식으로 '자식 노드'를 삽입한다.
    만약 이 자식 노드가 기존에 웹페이지 내에 존재하는 노드라면 이동된다.
    즉, 원래 위치의 이 '자식 노드'는 삭제된다.
    javascript MDN - appendChild()
  • 부모 노드.insertBefore(자식 노드, 이미 있는 다른 자식 노드)
    '부모 노드'의 자식으로 해당 '자식 노드'를 삽입하되,
    '이미 있는 다른 자식 노드'의 앞으로 삽입한다.
    만약 '이미 있는 다른 자식 노드'대신 null을 입력하면 '자식 노드'가 마지막 자식으로 삽입된다.
    참고로 insertAfter()는 없다.(봤다면 그건 jQuery 메서드일 가능성이 높다.)
    javascript MDN - insertBefore()

update

생성한 요소에 클래스, 아이디 등을 추가하거나 텍스트 콘텐츠를 추가할 때 사용한다.

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

//클래스 추가
menu.classList.add('menu');
//아이디 추가
menu.id='myMenu';
//텍스트 추가
menu.textContent='마이메뉴';
//속성추가 - setAttribute('속성명', '값')
menu.setAttribute('data-menu','my_menu_01');

참고: javascript MDN - setAttribute()

delete

요소 자체를 지우는 방법은
지우려고 하는 요소.remove();
구문을 사용하면 된다.
만약 해당 요소는 남겨두고 안의 자식 요소만을 모두 지울때는 innerHTML을 사용할 수 있다.

const content=document.querySelector('#content');

//자식 요소 모두 지우기 1 - innerHTML
content.innerHTML=''; //빈 문자열. 자식 요소 모두 삭제
//자식 요소 모두 지우기 2 - 반복문 사용
while(content.firstChild){
  content.removeChild(content.firstChild);
}

//특정 요소 모두 지우기 1 - for문 사용
const menuItems=document.querySelectorAll('.menu');
for(let i of menuItems){
  i.remove();
}
//특정 요소 모두 지우기 2 - forEach 사용
menuItems.forEach(function(menu){
  menu.remove();
});

innerHTML을 사용하여 지우면 간편하지만 보안문제가 있을 수 있으므로 권장하는 방법은 아니다.

참고:

Ch3. 이벤트 객체

DOM을 활용해 이벤트, 이벤트 핸들러를 구현할 수 있다.
쉽게 말하면 웹사이트에서 클릭, 드래그, 스크롤 등의 사용자 동작을 이벤트라고 하며, 그 이벤트 발생시의 내용을 담은 함수를 이벤트 핸들러라고 한다.

아래는 이벤트를 작성하는 여러 방법이다.

//이벤트1
element1.onclick=function(event){
  console.log('이벤트 실행!');
  console.log(event);//이벤트 객체 확인이 가능하다.
  console.log(event.target); //이벤트 대상
};
/*
대상: element1
이벤트: onclick (클릭 이벤트)
이벤트 핸들러: 함수 안의 내용
*/

//이벤트2 - 이벤트 핸들러는 따로 함수로 처리할 수 있다. 문법 주의!
element2.onclick=eventHandler;//소괄호 없으니 주의!

function eventHandler(event){
  console.log('이벤트 실행!');
  console.log(event);//이벤트 객체 확인이 가능하다.
  console.log(event.target);//이벤트 대상
}

//이벤트3 - addEventListener 사용 (권장!)
element3.addEventListener('click', eventHandler);
//eventHandler 자리에 익명함수를 작성해도 된다. 화살표 함수도 가능

이벤트도 객체이며 console.log()로 확인해보면 자세한 내용을 확인 할 수 있다.
또한 event.target 역시 콘솔로 확인해보면 html요소를 확인할 수 있다.

위에서 확인한 event 객체, event.target이 html요소인 점을 활용해 다양한 기능을 만들어 볼 수 있다.

이벤트 종류 (자주 사용하는 이벤트)

자주 사용하는 이벤트, 좀 더 학습이 필요한 이벤트를 정리해 보았다.
(on 이벤트)

EventDescription
onchangeHTML요소가 변할 때
onclickHTML요소를 클릭할 때
onmouseoverHTML요소에 마우스를 올렸을 때
onmouseoutHTML요소에 마우스를 올렸다 나갈 때
onkeydown키보드를 눌렀을 때
onkeyup키보드를 눌렀다가 땠을 때
onload브라우저가 웹페이지 로딩을 마쳤을 때
onsubmit웹페이지의 폼이 제출되었을 때

위의 '여러 이벤트의 종류' 외에 이벤트에 대해 좀 더 쉽게 학습할 수 있는 링크를 찾아보았다.
참고:


질문해보기

1. node와 element의 차이?
node는 HTML요소 뿐만 아니라 그 안의 콘텐츠 요소, 텍스트 등도 node로 간주한다. 반면 element는 말 그대로 HTML의 요소를 의미한다.
만약 console.dir()를 사용해 어떤 HTML요소를 확인해 본다면, 해당 속성 중 children과 childNodes를 발견할 수 있다. childNodes는 텍스트 요소까지 포함하며, children은 자식노드 중 element만을 나타낸다.
때문에 이 차이를 명확히 알고있어야 나중에 DOM을 조작할 때 혼란스럽지 않다.
참고: stackoverflow - node, element 차이

2. document.createDocumentFragment()
여러 HTML요소를 생성할 경우, 여러 차례 생성한 뒤 한 번에 HTML구조에 적용할 수 있도록 한다. 각각의 요소를 생성한 후 실제 HTML에 바로 append하지 않고 document.createDocumentFragment()에 append 한 뒤, 이 document.createDocumentFragment()를 실제로 append한다.
즉 말그대로 조각 모음 역할을 한다.

  • 그냥 append하는 것과 무슨 차이가 있을까?
    브라우저를 그때그때 append하면 그 때마다 브라우저는 웹페이지를 렌더링하거나 필요한 작업을 추가로 해야 한다. 이를 다른 말로 리플로우(참고링크)라고 한다. 때문에 document.createDocumentFragment()를 사용하면 더 나은 퍼포먼스를 기대할 수 있다.

참고: javascript MDN - createDocumentFragment()

3. <template> tag는 무엇인가
자바스크립트로 HTML코드를 생성하기 위한 일종의 HTML 태그이다.
HTML에 작성하지만 브라우저가 따로 렌더링하지는 않는다.
지원하지 않는 브라우저를 잘 확인하고 사용해야 하므로 주의가 필요하다.

참고: javascript MDN - template

4. 정규표현식이 뭐지?
정규표현식은 문자열이 특정 패턴과 일치하는지 검색해주는 기능을 한다.
정규표현식을 사용하면 조건문, 반복문이 없어도 문자열 검색을 검색을 편리하게 할 수 있다.
다만 내용이 복잡하고 양이 많기에 지금은 자세히 다루지 않고 추후 좀 더 학습할 예정이다.

//1. 정규 표현식 리터럴
/\d/g
/*
앞 뒤의 / : 시작, 종료 기호
\d : 패턴
g : 플래그(flag)
*/

//2. 생성자 함수
new RegExp('abc');

참고:

profile
프론트엔드 개발자 NH입니다. 시리즈로 보시면 더 쉽게 여러 글들을 볼 수 있습니다!

0개의 댓글