DOM조작
<template>태그
HTML조각을 만들어내는 방법
실제로 화면에 랜더링되기 전까지는 (script를 이용해 어딘가 붙여넣기 전까지는)
화면에 보이지 않는 HTML조각 ➜appendChild 등으로 랜더링해주면 그때 화면에 보이게된다
HTML
<template id='will-be-rendered'>
<span>변경 후</span>
</template>
<div id='target'>변경 전</div>
화면에 변경 전만 출력되어있다
변경 후에는 target의 변경 전이 사라지고 template안쪽에 들어있던 span의 내용이 target에 붙게된다
<div id='target'>
<span>변경 후</span>
</div>
template태그특성
만들어서 뭔가를 적어둬도 변경 전만 보이고 변화가 화면에 보이지 않는다
<template id='will-be-rendered'>
<span>무언가를</span>
</template>
아래에 반복적으로 재사용하고자 하는 부분(여기서는 <span>무언가를</span>)을 계속 추가하고 싶은 경우에 사용하면 좋다
<div id='target'>변경 전
<span>무언가를</span>
<span>무언가를</span>
<span>무언가를</span>
</div>
<template>태그와 <div>를 모두 가져오기-document.querySelector('')let target = document.querySelector('#target');
let tmpl = document.querySelector('will-be-rendered');
<template>를 통째로 복사복제해서 target에 집어넣는다let element = document.importNode(tmpl.content, true); //element는 <span>의 내용을 담게된다
target.appenChild(element); //무언가를을 자식으로 넣는다
화면결과
변경 전 무언가를
document.createElement로 span을 만들지 않아도 <template> </template>안의 내용을 바로 랜더링할 수 있다
다른예제
<template id='will-be-rendered'>
<li>
<div class='username'>아이디</div>
<div class='tweet'>트윗내용</div>
<div class='date'>2020-04-08</div>
</li>
</template>
이렇게 해두고
let target = document.querySelector('#target');
let tmpl = document.querySelector('will-be-rendered');
let element = document.importNode(tmpl.content, true);
element.querySelector('.username').textContent = 'Steve'
//element에 username을 steve로
//element에서도 querySelector사용가능
//element( <li> )의 하위자식내에서 querySelect
target.appenChild(element);
let element2 = document.importNode(tmpl.content, true);
element.querySelector('.username').textContent = 'johnny'
//element2에 username을 johnny
target.appenChild(element);
... //이부분만 반복하면 반복하는만큼 <template>안에 작성한 내용들이 화면에 랜더링된다
innerHTML나 method보다 간편(난 아직잘모르겠다,,ㅜ머릿속 대혼란)
JSON :JavaScript Object Notation
데이터구조
데이터가 실제로 저장될 때 html태그같은 메타데이터를 포함하지 않은채로 key-value로 저장
➡객체object형태를 따른다
이런 js object를 나열해놓은 데이터가 JSON
많은 시스템에서 JSON이용 다른 언어에서도 이용
데이터JSON ➡ 톔플릿 ➡ 실제화면에 데이터가 형식에 맞게 렌더
객체를 가지고 html로 변환하는 작업
함수작성
✔ 객체를 input으로 받고 HTML element를 ouput으로
입력input
{
'user': '김코딩',
'msg': '악플을 달지말자'.
'created-at': '2020-01-24 00:00:01'
}
출력output
<li class ='comment'>
<img src ='avatar.png'>
<div class ='username'>김코딩</div>
<div class ='content'>악플을 달지말자</div>
<div class ='created-at'>2020-01-24</div>
</li>
변환결과가 1:1로 매칭된다
댓글 객체{} ➡li.comment
user 키 값 ➡키 값이 담긴 div.username
msg 키 값 ➡키 값이 담긴 div.content
created-at 기 값 ➡ (시간을 잘라낸)키 값이 담긴 div.createdAt
문제 접근
❌댓글시스템을 어떻게 html로 바꾸지?❌
❗객체를 html태그로 바꿔주자 -DOM 지식이 필요하다❗
필요한 DOM지식
li혹은 div엘리먼트를 생성하는 방법
엘리먼트를 만들어야 그 안에 내용을 넣을 수 있으니까
document.createElement('태그이름')*
엘리먼트에 class를 지정하는 방법
element.classList.add('클래스이름')
엘리먼트에 값을 채워넣는 방법
element.textContent = '채울 내용'
li 엘리먼트의 자식으로 div엘리먼트를 붙이는 방법(부모자식 관계 만드는 방법)
liElement.appendChild(divElement)
여러개의 댓글을 출력하는 함수 printComments() 작성
- 하나의 댓글을 출력하는 printComment(comment) 반복실행
- 하나의 댓글을 html로 바꾸고
makeCommentElement(comment)
- 만들어진 댓글 html을 읽기영역에 붙여 출력
readingArea.appendChild(commentElement)
function makeCommentElement(comment){ //comment는 li태그를 나타냄?
//li엘리먼트 만들기
let liElement= document.createElement('li');
//div.username 엘리먼트 만들기
let usernameElement = document.createElement('div');
usernameElement.classList.add('username');
//div.username에 내용채우기
usernameElement.textContent= comment.user;
//li의 자식으로 div.username 엘리먼트 붙이기
liElement.appendChild(usernameElement);
return liElement;
}
let DATA= [
{ 'user': '김코딩', 'msg': '악플을 달지말자'. 'created-at': '2020-01-24 00:00:01'}, .....
]
function printComments(){
DATA.forEach(printComment);
}
function printComment(comment){
let commentElement = makeCommentElement(comment);
readingArea.appendChild(commentElement);
}
function makeCommentElement(comment){
//생략
return liElement;z
}
목적에 맞는 함수 만들고 문제를 분해해서 읽기 쉬운 코드 작성
일단 하나의 함수에 일단 돌아가게끔 작성해서 메소드들을 충분히 연습해야한다
처음엔 하나의 함수에 모든것을 작성해도 좋지만
작업단위가 분명해지면
하나의 함수가 한가지 작업만 하는 것이 가장 좋은방법 ➡그래야 유닛테스트도 가능해진다
유효성 검사(form validation)
버튼을 클릭했을 때, (혹은 실시간으로) 그 입력값이 유효한지 아닌지 판단하는 JavaScript 함수를 연결
실제 개발 과정에서 정말 많이 부딪히는 문제 중 하나
버튼 클릭등의 이벤트를 발생시키고, DOM을 통해 값을 얻어내고, 함수를 연결시키는 과정을 연습