개발 R.I.P.

6.16 Dev.Feedback(JS상에서 DOM을 이용해 HTML 구성하기)

편행 2021. 6. 16. 14:42
반응형

DOM의 사용법에 대해 아주 기초적인 지식만 공부했기에, Javascript상에서 DOM이 어떤식으로 작동하는지에 대해

확실히 이해를 하지 못했다. 그래서 막상 알고리즘을 짜거나 코드를 작성할 때 문제가 생기곤 한다.

 

첫 번째 알게된 점 

template literal로는 appenChild를 할 수 없다는 것

const frag = document.createDocumentFragment(); 
const domString = `<li><a class = "name">'let's test!!'</a></li>`
frag.appendChild(domString);
const body = document.body; body.appendChild(frag); alert(body.lastChild.tagName);

위 코드를 실행해보니 

오직 Node만 파라미터로 사용해야 한다고 한다. 그렇다면 이걸 해결하기 위해선 어떻게 해야할까?

const frag = document.createDocumentFragment(); 
const liNode = frag.appendChild(document.createElement("li"));
const aNode = frag.appendChild(document.createElement("a"));
aNode.textContent = "let's test!!";
aNode.setAttribute("class", "name");
const body = document.body; body.appendChild(frag); alert(body.lastChild.tagName);

이런식으로 각각 template literal을 사용하지 않고, 각각 나눠주면서 사용하는 방식이 있다.

 

다른 방식은? 가상의 div를 만들고 거기에 innerHTML을 통해 template literal 방식으로 만들어준 태그들을 넣어준다.

그리고 자식 노드를 넣어주는 방식을 사용한다. 만일 어떤 특정한 요소만 넣어주고 싶다면, 그 요소를 정확히 선택하는 조건문 혹은 반복문을 같이 섞어써주면 될 것이다.

const fakeEl = document.createElement('div');
const domString = `<li><a class = "name">'let's test!!'</a></li>`
fakeEl.innerHTML = domString
const body = document.body; body.appendChild(fakeEl.firstChild); 

이 방식이 확실히 더 간편해 보인다. 근데 의문이 하나 드는게 있다.

 

 innerHTML 얘를 써도 되는 것인가????? 보안적으로 문제가 생기지 않을까?

위에 코드를 살펴보면 전혀 문제가 되지 않는다!

innerHTML을 사용하긴 해줬지만, 그것이 사용자에게 직접적으로 노출이 되지 않는다. 그냥 자식요소를 넣어주기 위해 사용되는 것일 뿐

그 요소를 넣어주곤 그냥 사라져버린다.

 

이런 포인트를 잘 기억해야한다. 무조건 위험하다고 아예 등한시 해버리면, 막상 편하게 쓸 수 있는 부분에서 쓰지 못하는 경우가 생겨버린다. 분명 현재에 와서는 문제로 발생했지만, 그전까지는 썼던 메소드들이다. 제대로 확인해보고 공부해야 한다.

 

두 번째 알게된 점 

 

map의 구동방식

function makeTag(arr) {
  // arr의 요소를 사용해서 HTML을 구성한다.
  arr.map((item)=>{
    const container = document.createElement('div')
    const domString = `<li><a class = "hobby">${item.hobbyName} </a><div class = "howMuch">${item.howMuch}</div></li>`
    container.innerHTML = domString;
    document.querySelector('body').appendChild(container.firstChild);
  }) 
}

let hobbyList = [
  { hobbyName: 'Swimming', howMuch: 97 },
  { hobbyName: 'Running', howMuch: 42 },
];

위의 코드를 짰을 때, appendChild 에서 firstChild를 사용하는 부분때문에 갖게된 의문이다.

개념이 부족하기에 갖게된 의문

위의 코드를 보면 hobbyList의 요소인 객체 내부의 값이 a 태그와 div태그에 나타나는 코드인데

container 내부에 전체 요소가 먼저 들어가고,즉 자식 요소가 여러개가 먼저 구성이 되고나서 firstChild를 따로 넣어주는지

아니면 container 내부에 자식 요소를 한개만 넣어주고 그게 body에 추가가 되고, 다시 처음부터 돌아가게 되는지

이 두가지 경우가 확실하지 않았다.

 

결론은 후자!

너무 당연한 결과였지만, 주변 사람들에게도 물어보기도 하고 콘솔도 찍어보면서 고민을 해봤다.

막상 직접 콘솔도 찍어보고 해보고 나서 설명을 들으니 확실히 이해가 됐다.

 

역시 직접 다 해보고 정확한 궁금증을 알고 나서 질문을 해야한다는 것을 다시 한 번 깨닫게 되는 하루였다.

반응형