게시글

강좌20 - HTML&DOM - 2년 전 등록 / 일 년 전 수정

HTML에 데이터 저장하기

data-속성과 dataset
조회수:
0

안녕하세요. 이번 시간에는 HTML에 데이터를 저장하는 방법에 대해서 알아보겠습니다. 그동안 HTML에 데이터를 저장하기 위해 input[type='hidden']을 쓴다든가 하는 꼼수를 쓰는 것을 보셨을 것입니다. 하지만 HTML5가 도입되면서 HTML에도 데이터를 저장할 수 있게 되었고, 자바스크립트로 간단하게 가져올 수 있습니다.

다음 예시를 살펴보겠습니다.

<table>
  <tr>
    <th>이름</th>
    <th>나이</th>
    <th>삭제</th>
  </tr>
  <tr>
    <td>zero</td>
    <td>25</td>
    <td><button class="del-btn">삭제</button></td>
  </tr>
  <tr>
    <td>nero</td>
    <td>32</td>
    <td><button class="del-btn">삭제</button></td>
  </tr>
</table>
<script>
  Array.prototype.forEach.call(document.querySelectorAll('.del-btn'), function(btn) {
    btn.addEventListener('click', function(e) {
      // 여기를 작성해야 합니다.
    });
  });
</script>

서버에서 반복문으로 사용자 목록을 렌더링한 결과입니다. php, jsp나 노드의 템플릿 엔진 등에서 반복문으로 HTML 렌더링 해보셨죠? script 태그 안의 내용은 알아두시면 좋습니다. 제이쿼리 없이 여러 태그(.del-btn 버튼들)에 이벤트를 동시에 다는 방법입니다. 

세 번째 칸이 해당 로우의 사용자를 삭제하는 버튼이 들어가는 곳입다. 이벤트 리스너는 달아놨는데 버튼을 눌렀을 때 해당 유저의 아이디를 어떻게 가져오실 건가요?

방법이야 많습니다. 어딘가에 사용자의 아이디를 넣어두어 DOM traversing으로 찾아면 되겠죠. nero의 아이디인 2를 어딘가에 넣어봅시다.

<tr>
  <td>nero</td> 
  <td>32</td>
  <td><button class="del-btn">삭제</button></td>
  <td style="display:none">2</td>
</tr>

이렇게 보이지 않는 마지막 칸에 넣을 수도 있고,

<tr>
  <td>nero</td>
  <td>32</td>
  <td><input type="hidden" value="2"><button class="del-btn">삭제</button></td>
</tr>

이렇게 hidden input을 만들어서 하시는 분도 봤습니다. 이처럼 데이터를 HTML 어디에 욱여넣으면 좋을까 고민하시는 분들이 많습니다. 그런데 위의 방법보다 깔끔한 방법이 있습니다. HTML의 data-속성을 사용하는 것입니다. data-id data-name data-age 등, 앞에 data-만 붙여주면 됩니다.

아래처럼 할 수 있는 것이죠. 아이디 말고도 여러 데이터를 같이 넣어봅시다. 직업과 결혼여부도 넣어봤습니다.

<tr data-id="2" data-job="emperor" data-married="true">
  <td>nero</td>
  <td>32</td>
  <td><button class="del-btn">삭제</button></td>
</tr>

버튼에서 tr로 찾아가는 코드를 보여드리기 위해 일부러 tr에 넣어봤습니다. 실제로는 버튼에 데이터를 넣으면 더 편합니다.

스크립트에서는 아래와 같이 접근 가능합니다.

<script>
  Array.prototype.forEach.call(document.querySelectorAll('.del-btn'), function(btn) {
    btn.addEventListener('click', function(e) {
      var tr = e.target.parentNode.parentNode;
      console.log(tr.dataset);
    });
  });
</script>

tr.dataset의 값은 { id: "2", job: "emperor", married: "true" }입니다. 문자열로 저장되기 때문에 숫자나 불린 값들은 알아서 파싱하셔야 합니다. HTML5에서 공식 지원하는 데이터 속성이라서 자바스크립트 DOM API에서도 dataset 속성으로 접근할 수 있는 것입니다. 이렇게 데이터를 저장하는 기능을 자체적으로 지원하기 때문에 지저분한 방법은 더 이상 사용하지 맙시다.

반대로 dataset에 데이터를 저장하면 HTML 태그에 속성이 추가됩니다. tr.dataset.test = 'string';을 한다면 tr 태그에 data-test="string"이 추가됩니다. 이렇게 자바스크립트를 사용해서도 임시로 HTML에 데이터를 저장할 수 있습니다.

dataset은 자바스크립트이기 때문에 속성명을 camelCase로 변환해버립니다. data-create-date라면 dataset 안에는 createDate로 저장됩니다. 반대로 dataset.monthSalary = '500'을 했다면 data-month-salary가 되는 것입니다.

제이쿼리에서는 $(선택자).data(속성, 값)으로 가능합니다.

이미 많은 분들이 깨달으셨겠지만 HTML에 데이터를 넣는 것이기 때문에 누구에게나 보이고, 자바스크립트로 접근 가능하기 때문에 누구나 수정할 수 있습니다. 민감한 데이터는 넣지 않도록 합시다.

투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.

댓글

4개의 댓글이 있습니다.
3달 전
글내용과는 조금 다른 질문인데요. 혹시 실시간으로 데이터를 받아와서 데이터베이스에 넣고 프론트에서 데이터요청을 하면 백엔드에서 데이터베이스에 있는 데이터를 가지고와서 데이터 전처리를 해서 프론트에 주게되고 프론트에서는 화면에 그래프를 나태내려고합니다.
(여기서 그래프는 메뉴에 체크박스식으로 클릭할 수 있게 해놓고 그에 맞는 그래프를 화면에 출력할려고합니다)
프론트는 리액트 백엔드는 장고를 사용하려고 합니다. 여기서 궁금한점이 백엔드를 노드로 해도 성능에 차이가 없는지가 궁금합니다.
4달 전
노드로 하는게 성능이 더 좋습니다. 머신러닝과 연관된 거면 파이썬이 낫습니다.
4달 전
dfasfdsfadf
일 년 전
df
일 년 전
안녕하세요! 글이 정말 도움되었습니다! 근데 첫번째 소스에 addEventListener가 addEventListender로 오타가 있어서 댓글 답니다!
일 년 전
감사합니다~