yes! 👌
DOM(Document Object Model)은 JavaScript를 이용해서 HTML, CSS에 접근해서 변경할 수 있게 해 주는 다리라고 생각할 수 있다.
console.dir($0)
엘리먼트를 객체 형식으로 볼 수 있다! ($0
외에도document.body
등 가능하다.)
HTML과 DOM 모두 트리구조를 가지고 있다!
<script>
태그가 적용되는 위치에 따라서 실행 결과가 달라질 수 있음을 이해할 수 있다.웹 브라우저는 코드를 해석하는 과정에서
<script>
를 만나면HTML
해석을 멈추고<script>
를 해석한다. DOM이 형성되기 전에<script>
를 불러온다면<script>
에서는 생성되지 않은 DOM을 제대로 처리하지 못한다. 따라서body
의 가장 아래에 위치하는 게 좋다.
yes! 🙌
Dom으로 HTML에 CRUD를 할 수 있다!
document.createElement()
: 엘리먼트를 생성한다.const newDiv = document.createElement('div');
.querySelector()
: 첫번째 엘리먼트를 조회한다.
.querySelectorAll()
: 해당되는 모든 엘리먼트를 조회하고 유사배열로 담을 수 있다.const oneList = document.querySelector('div') const allLists = document.querySelectorAll('div')
앞에는
document
,element
가 올 수 있고,()
안에는'tag'
,'#id'
,'.class'
등이 올 수 있다.
.textContent
: 문자열을 입력할 수 있다. 앞서 선언한 변수newDiv
를 활용해보면,newDiv.textContent = "Hello" console.log(newDiv) // <div>Hello</div>
.classList.add()
: CSS와 연결을 위한 class를 추가한다.newDiv.classList.add('.tweets-list'); console.log(newDiv) // <div class="tweets-list">Hello</div>
.setAttribute("name", "value")
: "name"의 "value"를 바꿀 수 있다.const container = document.querySelector('#container') console.log(container) // <div id="container">...</div> container.setAttribute('id', 'change') console.log(container) // <div id="change">...</div>
.remove()
: 엘리먼트를 삭제한다. 엘리먼트를 알고 있을 때 유용하다.const newDiv = document.createElement('div'); newDiv.remove(); // 원하는 엘리먼트를 삭제한다.
.removeChild()
: 반복문을 활용하여 원하는 자식 엘리먼트들만 여러 개 삭제할 때 유용하다.const container = document.querySelector('#container') while (container.firstChild) container.removeChild(container.firstChild) // 이러면 모든 자식엘리먼트들을 삭제할 수 있다!
innerHTML = ""
: 엘리먼트를 지울 수 있다. 하지만 보안공격에 취약하므로 쓰지말자.document.body.innerHTML = ""; // body의 속성을 지워서, 이러면 전체 내용을 지울 수 있다.
.textContent = ""
: 이렇게 텍스트 내용을 비게 만들어서 지울 수도 있다.
앞서 만들었던 엘리먼트를 자식요소로 추가해서 Dom으로 연결해 준다.
.append()
: Dom에 적용하여 자식요소로 연결해 준다. 한 번에 여러 개 연결이 가능하다.const container = document.querySelector('#container'); container.append(newDiv); // container에 newDiv를 연결해 준다.
.appendChild()
: 자식요소로 자식들의 마지막에 연결해 준다. 한 번에 한 개만 추가할 수 있다.append
는 반환값이 없지만appendChild
는 반환값이 있다. (~Child
들은 반환값이 있다.)const container = document.querySelector('#container'); container.appendChild(newDiv); document.querySelector('#container').appendChild(newDiv); //이렇게도 가능하다.
innerHTML
은 'Element'속성을 가지므로 해당 'Element'의 'HTML'을 읽을 수 있다.textContent
는 'Node'속성을 가지므로innerHTML
와 달리 '태그'를 제외하고 '텍스트 값'을 그대로 읽어온다. 결론적으로는 성능과 보안에 강점이 있는textContent
를 쓰도록 하자.
첫번째 인자의 값만 나온다.
document.querySelector('div', 'body') document.querySelector('div') //같은 값이 나온다.
yes!
node
는 DOM API상에 존재하는 모든 것을 포괄한다.element
는node
의 한 종류로,node
로부터 메소드와 속성을 상속받는다.
.children
: 현재 요소의 자식 요소를 반환한다.
.childNodes
: 현재요소의 자식 요소들의 태그노드, 텍스트 노드들을 모두 반환한다.(비요소 노드를 포함한다.)<body> <div id="container" class="highlight"> 부모입니다. <span>자식1입니다.</span> <span>자식2입니다.</span> </div> </body>
이 경우, '#container'의 'children'은 'span, span'이고, 'childNodes'은 'text, span, text, span, text'이다.
.remove()
: 노드를 메모리에서 삭제하고 종료한다.
.removeChild()
: 부모 노드와 관계를 끊어 Dom 트리와 연결을 해제한다. 메모리상에서 바로 삭제하지 않고, 반환값으로 삭제한 노드를 참조하므로 다른 변수에 담아 위치를 이동할 때 유용할 수 있다.let container = document.querySelector('#container'); let containerRemove = container.removeChild(container.firstChild); document.body.append(containerRemove);
위와 같이 body의 자식 요소로 container에서 삭제했던 targetRemove를 연결할 수 있다.
Array.from(newDiv)
,
Array.prototype.slice.call(newDiv)
: 이러면 배열처럼 만들어서 변수에 저장해 각 요소들을 배열의 요소로 접근해서 쓸 수 있다! 어떻게? 배열은 주소를 갖고 있기 때문이다.const newDiv = document.querySelectorAll('.tweets-list'); const array1 = Array.from(newDiv); const array2 = Array.prototype.slice.call(newDiv);
두 메소드 모두
[li.tweets-list, li.tweets-list, ... , li.tweets-list]
이런 결과를 나타낸다. 각 인덱스의 요소가 같은 class이기 때문에 같아 보이지만 각각의 다른 정보를 담고 있다!
아 니 다! 🙅♀️
.appendChild
의 주의점 중 하나로, 같은 엘리먼트를 복사한다면, 새로운 곳에 생성되는 것이 아니라 새로운 곳으로 위치가 이동된다! 그러니 주의하자.