이전에 크롬 앱 Momentum을 클론코딩하면서 다뤄봤던 개념들이었지만, 체계적인 개념 정리 없이 클론코딩만 하기 급급하다 보니 내가 했던 것이 DOM이라는 것도 모르고 사용했다는 것을 깨닫게 되었다. 이번 기회에 CRUD를 위주로 DOM을 학습하면서, 큰 뼈대를 잡고 내가 하는 것이 무엇인지 파악한 채 코드를 작성하게 되었고 좀 더 머릿속이 정리가 되는 느낌이 들었다.
<script>
요소를 만나면, 웹 브라우저는 HTML 해석을 잠시 멈추고(일시정지), <script>
요소를 먼저 실행함<script>
요소는 등장과 함께 실행됨<head>
요소에 <script>
요소를 추가한다면, <body>
의 요소가 <script>
에 있는 경우 오류를 일으킬 수 있음<body>
에 <script>
를 추가하는 것이 바람직함document
객체에 구현되어 있음console.dir
→ DOM을 객체의 모습으로 출력document.createElement('')
document.body.append()
부모노드.insertBefore(삽입 할 노드, 기준 점 노드);
appendChild()
특정 부모 노드의 자식 노드 리스트 중 마지막 자식으로 붙임 (prependChild라는 건 없음)after()
, insertAfter()
지정한 요소(참조된 노드) 뒤에 새로운 요소를 삽입before()
, insertBefore()
지정한 요소(참조된 노드)의 시작 부분에 내용(특정 부모 노드의 자식 노드)을 삽입const oneTweet = document.querySelector('.tweet')
selector
)를 전달하여 HTML element의 정보를 조회querySelectorAll
사용get
으로 시작하는 DOM 조회 메서드(getElementById(’’)
) → querySelector 와 비슷한 역할을 하는 오래된 방식이라고만 이해하면 됨. 실제 동작은 동일getElementsByTagName()
태그 name 파라미터에 일치하는 모든 자손 element의 집합을 생성getElementsByClassName()
주어진 클래스 이름을 가진 모든 자식 element의 실시간 HTMLCollection을 반환querySelector
등을 이용해 가져온 후 value
라는 속성으로 접근 가능// const oneDiv = document.createElement('div'); // <div></div>
oneDiv.textContent = 'dev'; // 내용 추가 <div>dev</div>
oneDiv.classList.add('tweet'); // class 추가 <div class="tweet">dev</div>
Element.id
로 부여setAttribute
class와 id 말고 다른 attribute 추가// element.setAttribute( 'attributename', 'attributevalue' )
let aElement = document.createElement('a')
aElement.setAttribute('id', 'javascript')
aElement.textContent = 'JS' // <a id='javascript'>JS</a>
value
속성을 통해 element 입력값 설정container.append(tweetDiv)
tweetDiv.remove()
여러 개의 자식 요소 지우기
innerHTML
로 가능하지만, 보안에서 몇 가지 문제를 가지고 있음removeChild
→ 자식 요소를 지정해서 삭제하는 메서드removeChild
와 반복문(while, for, etc.)을 활용하여 모든 자식 요소를 삭제remove와 removeChild 비교
removeChild
메모리에 해당 노드는 그대로 존재하며, 부모 노드와의 부모-자식관계를 끊어 DOM 트리에서 해제하는 것임. 최종적으로는 관계를 끊은 해당 노드의 참조를 반환const deleteId = document.querySelector('#delete');
// deleteId의 첫 번째 자식 요소가 존재하면, 첫 번째 자식 요소를 제거
while (deleteId.firstChild) {
deleteId.removeChild(deleteId.firstChild)
}
// deleteId의 자식 요소가 1개만 남을 때까지 마지막 자식 요소를 제거
while (deleteId.children.length > 1) {
deleteId.removeChild(deleteId.lastChild);
}
// 클래스 이름이 tweet인 요소만 찾아서 제거
const tweets = document.querySelectorAll('.tweet')
tweets.forEach(function(tweet){
tweet.remove();
})
// or
for (let tweet of tweets){
tweet.remove()
}
display: none
브라우저에서 아예 영역조차 사라짐visibility: hidden
엘리먼트가 차지하는 영역을 그대로 남겨놓음.test(str)
주어진 문자열이 정규 표현식을 만족하는지 판별하고, 그 여부를 true 또는 false로 반환함 /^hello/.test(str);
이벤트 핸들러
이벤트가 발생할 때 실행되는 함수 → 사용자가 element에 특정 이벤트를 발생시켰을 때 이벤트 핸들러가 동작on
이라는 접두어가 붙음이벤트 객체
사용자 입력을 트리거로 발생한 이벤트 정보를 담은 객체event.target
.onclick
직접 객체에 지정 / .addEventListener()
메서드 사용해서 할당btn.onclick = function(){
console.log();
}
btn.addEventListener('click', function(){
console.log();
});
function handler(){
console.log();
}
btn.onclick = handler;
.getElementsByTagName
은 HTMLCollection으로 리턴을 하는데, .querySelectorAll
은 NodeList로 리턴을 한다. HTMLCollection과 NodeList의 차이가 뭔지 궁금하다.?=.*
가 뭘 뜻하는지도 궁금하다.