기본기부터 다시 잡고 가자는 마음으로 처음부터 시작하고 있다.
그러다가 append
로 DOM에 Element를 추가하는 코드를 어쩌다가 보게 되어서 테스트를 해 봤는데 appendChild
와의 차이점에 의문을 갖게 되어 정리하고자 한다.
append와 appendChild 둘다 부모 요소에 자식 요소를 추가하는 기능이다.
우선 append와 appendChild의 예시를 보자
common html code
<body>
<div class="app">
<h1>append Vs appendChild</h1>
</div>
</body>
append code
const container = document.querySelector(".app");
const p = document.createElement("p");
$app.append(p)
👉🏻 <app><p></p></app>
appendChild code
const container = document.querySelector(".app");
const p = document.createElement("p");
$app.appendChild(p)
👉🏻 <app><p></p></app>
둘다 부모 요소인 container 아래 p element는 자식 요소로서 추가되는 것을 알 수 있다.
const container = document.querySelector(".app");
const p = document.createElement("p");
p.textContent = "paragraph";
const div = document.createElement("div");
div.textContent = "box";
const a = document.createElement("a");
a.textContent = "anchor";
container.append(...[p, div, a]);
아래 결과를 보면 p, div, a
요소 모두가 추가가 됨을 볼 수 있다.
📒 append는 appendChild와 다르게 여러 요소를 받아서 DOM에 추가할 수 있다.
어떤 요소를 선택해서 childrenNodes를 보면 text fragment
를 볼 수 있다. text는 DOM에 text fragment
로 추가되기 때문에 fragement도 한 요소로서 createTextNode, textContent, innerHTML
을 이용해서 appendChild
로 넣어준다. 설명이 좀 어렵게 느껴질 수 있지만, 중요한 점은 text도 요소로서 fragment
로 파싱이 되어야 DOM에 추가될 수 있다는 점이다.
아래는 기본적으로 내가 많이 봤던 형태이다.
const container = document.querySelector(".app");
const p = document.createElement("p");
const pText = document.createTextNode("paragraph"); // 1️⃣
p.appendChild(pText); // 2️⃣
p.innerHTML = "paragraph";
container.append(p);
1️⃣과 2️⃣를 합쳐서 아래와 같이 작성할 수도 있다.
p.innerHTML = 'paragraph'
와 같은 경우는 브라우저가 자동으로 fragment로 파싱을 해준다.
위처럼 3가지의 경우
처럼 text를 넣어줄 수 있으나 append를 이용하여 바로 text를 추가할 수 있다. 즉, 자동으로 text fragment
로 변환해준다는 것이다.
const container = document.querySelector(".app");
const p = document.createElement("p");
p.append("paragraph");
container.append(p);
결과
잘 작동함을 확인할 수 있다.
📒 append는 appendChild와 달리 text를 인자로 받아
암묵적으로 fragment로 변환
해 주는 작업을 한다.
append는 return값이 존재하지 않는다.
const container = document.querySelector(".app");
const p = document.createElement("p");
p.append("paragraph");
console.log(container.append(p)); // 1️⃣
위 코드의 주석 1️⃣을 이용하여 return값이 있는지 확인해 보면 아래와 같이 undefined
가 나옴을 알 수 있다.
📒 append는 appendChild와 달리 return 값이 존재하지 않는다.
const container = document.querySelector(".app");
const p = document.createElement("p");
p.textContent = "paragraph";
const div = document.createElement("div");
div.textContent = "box";
const a = document.createElement("a");
a.textContent = "anchor";
container.prepend(...[p, div, a]);
📒 그냥 append는 부모요소의 만 하단에 추가되는 것과 달리
부모 요소 아래 최상단에 위치
시킨다.
const container = document.querySelector(".app");
const p = document.createElement("p");
p.textContent = "paragraph";
const div = document.createElement("div");
div.textContent = "box";
const a = document.createElement("a");
a.textContent = "anchor";
container.appendChild(...[p, div, a]);
내 예상은 1 argument expected but 3 arguments are taken
과 오류가 날 줄 알았지만 오류보단 잠재적 오류
가 발생했다. 아래 그림에서 보면 가장 처음에 넣어주는 p 요소
만 추가됨을 볼 수 있는데 오류라고 하기엔 애매한 것은 (여기)[https://levelup.gitconnected.com/always-pass-one-argument-to-your-javascript-function-4140d909937e]를 참고하면 알 수 있다.
함수에 정의된 parameter 개수보다 많은 인자가 들어오게 되면 나머지 값들은 무시되고, 함수에 정의된 parameter 개수보다 적은 인자가 들어오면 라벨링할 수 없는 parameter는
undefined
오로 정의된다.
👉🏻 이러한 이유 때문에 없는 key에 destructuring으로 접근하면 undefined
가 나오는 것이지 않을까 생각해본다.
const container = document.querySelector(".app");
const p = document.createElement("p");
p.appendChild("paragraph"); // ❌ Error!!
📒 발생한 오류에서 보다시피 appendChild는
Node type
만을 인자로 받는다. appendChild 메서드 내부 로직에 type을 검사하는 기능이 있는 것 같다.
const container = document.querySelector(".app");
const p = document.createElement("p");
p.textContent = "paragraph";
console.log(container.appendChild(p));
📒 console.log()로 appendChild의 return값을 찍어보면 추가된 요소를 확인할 수 있다.
appendChild는 prepend()
과 같은 것이 없지만 아래와 같이 다른 것을 쓰면된다.
1. insertBefore
2. insertAdjacentElement
- beforebegin: targetElement의 형제요소로서 바로 위에 추가
- afterbegin: targetElement의 자식요소로서 바로 아래 추가
- beforeend: targetElement의 자식요소로서 맨 아래 추가
- afterend: targetElement의 형제요소로서 바로 아래 추가
js를 대충 끝내고 react로 갔다가 부딪히는 수 많은 문제에서 결국 마음만 급하게 진행하여 기본기에 대한 것을 간과했던 것으로 append
함수 조차 몰랐다...;;😭 기본적은 DOM 조작인데도 불구하고..
하지만, 요새 기본기를 잡으면서 부딪혔던 문제에 대한 퍼즐조각들이 서서히 맞춰져 나가지는 기분이라 기분은 좋다.
append VS appendChild
append VS appendChild1
pass lots of parameters to restricted positional arguments function in js