DOM, Document Object Model. 어렵다고 듣기만 하다가 막상 접하니 처음 느낀 감정은 낯설음이었다. 그동안 접할 기회가 없었던 객체와 메소드와 속성값이 계속 튀어나온다. 하지만 논리적인 어려움은 아니라서 반복해서 사용하고 익숙해지면 될 문제다. 이런건 어렵다고 표현하기 보다는 낯설다고 표현하는게 맞다고 본다. 어렵지는 않았다. 내용이 방대해서 모든 내용을 정리할 수는 없지만 핵심 개념과 자주 등장하는 기능을 정리하고자 한다.
DOM (Document Object Model) 은 HTML 또는 XML (en-US) document와 상호작용하고 표현하는 API입니다. DOM은 browser에서 로드되며, 노드 트리(각 노드는 document의 부분을 나타냅니다)로 표현하는 document 모델입니다(예, element, 문자열, 또는 코멘트).
웹문서를 받으면 브라우저 렌더링 엔진에서 브라우저가 해석할 수 있게 DOM 형태로 메모리에 적재한다. 그리고 DOM API를 통해서 프로그래밍 언어(javascript)로 실시간으로 제어할 수 있다.
Node는 여러 가지 DOM 타입들이 상속하는 인터페이스이며 그 다양한 타입들을 비슷하게 처리할 수 있게 한다. 예를들어, 똑같은 메소드를 상속하거나 똑같은 방식으로 테스트를 할수있다
엘리먼트는 태그로 시작해서 태그로 끝난다.
엘리먼트는 다른 표현으로 엘리먼트 노드라고 부른다. 노드는 엘리먼트의 상위 개념이다.
let li = document.createElement('LI'); // 태그명은 대문자
li.className = 'comment';
li.textContent = '반갑습니다';
let parent = document.querySelector('#view-comments');
parent.appendChild(li)
li.remove();
console.log는 요소를 HTML과 같은 트리 구조로 출력합니다.
console.dir은 요소를 JSON과 같은 트리 구조로 출력합니다.
구체적으로, console.log는 DOM 요소에 대해 특별한 처리를 제공하지만 console.dir은 그렇지 않습니다. 이것은 종종 DOM JS 객체의 전체 표현을 보려고 할 때 유용합니다.
> elIdFailureFirstCharEng.className
< "id-failure-first-char-eng hide"
> elIdFailureFirstCharEng.className.length // 클래스 길이를 돌려주지 않음
< 30
> elIdFailureFirstCharEng.classList
< DOMTokenList(2) ["id-failure-first-char-eng", "hide", value: "id-failure-first-char-eng hide"]
> elIdFailureFirstCharEng.classList.length
< 2
input 태그의 있는 value 속성 값을 받아올 수 있음.
이 엘리먼트에 이벤트 리스너를 설치하면 입력할 때 마다 이벤트를 발생시키는 기능을 구현할 수 있음.
elInputUsername.onkeyup = function () {
if (isMoreThan4Length(elInputUsername.value)) {
elFailureMessage.classList.add('hide');
elSuccessMessage.classList.remove('hide');
} else {
elSuccessMessage.classList.add('hide');
elFailureMessage.classList.remove('hide');
}
// 특정 이벤트를 지울 수 있음
window.addEventListener('resize', console.log('resize1'))
// 모든 이벤트를 지워야 함
window.onresize = function () { console.log('window resize') }
<div id="first"><div id="second"><div id="third"></div></div></div>
추후 참조 URL : https://www.zerocho.com/category/JavaScript/post/57432d2aa48729787807c3fc
이벤트 버블링, 콜백 함수
display:none
으로 지정되어 보이지 않는 문자는 가져오지 않음. CSS 종속적.display:none
으로 지정된 문자도 가져옴$0.innerText
"유효성 검사\n아이디\n비밀번호\n비밀번호 확인"
$0.innerHTML
"\n 유효성 검사\n <!-- 동영상 강의에 나온 코드를 그대로 실습하세요 -->\n <div>아이디</div>\n <input type=\"text\" name=\"username\" id=\"username\">\n <div class=\"success-message hide\">사용할 수 있는 아이디입니다.</div>\n <div class=\"failure-message hide\">아이디는 네 글자 이상입니다.</div>\n - 중략"
$0.textContent
"\n 유효성 검사\n \n 아이디\n \n 사용할 수 있는 아이디입니다.\n 아이디는 네 글자 이상입니다.\n 영어와 숫자만 입력할 수 있습니다.\n 첫 글자는 영어만 입력할 수 있습니다.\n 비밀번호\n \n 비밀번호 확인\n \n 비밀번호가 일치하지 않습니다.\n 비밀번호가 8자리 이상, 특수문자 대소문자 하나씩 포함해야 합니다.\n 첫 글자는 영어만 입력할 수 있습니다.\n \n\n"
예제 HTML
<body>
<div>
여기 글자 있습니다.
<span>자식도 있습니다.</span>
<span>자식도 여럿 있습니다.</span>
</div>
</body>
예제 JS
$0.children
HTMLCollection(2) [span, span]
$0.childNodes
NodeList(5) [text, span, text, span, text]
$0.childNodes.forEach( function(value, key) {
console.log(key + ' / ' + value.textContent);})
0 /
여기 글자 있습니다.
1 / 자식도 있습니다.
2 /
3 / 자식도 여럿 있습니다.
4 /
// text(여기 엘리먼트 있습니다. <또는 공백>) + span(자식도 있습니다.) + text(공백) + span(자식도 여럿 있습니다.) + text(공백)
children
메소드는 엘리먼트를 돌려줌childrenNodes
메소드는 모든 노드를 돌려줌공백은 노드다. 공백은 엘리먼트가 아니다.
예제 HTML
<div data-user="steve" data-role="moderator" data-user-id="1">
Steve Lee
<div>
예제 JS
$0.dataset.user // 'steve'
$0.dataset.role // 'moderator'
$0.dataset.userId // '1'
dataset을 활용해서 HTML 속성에 data-
로 시작하는 숨겨진 속성을 넣고 dataset.
노드로 제어할 수 있음
특정 엘리먼트를 자식 엘리먼트에 추가하는 메소드.
이 동작은 이동을 일으킨다. 이전 위치에선 없어지게 된다.
append 동작으로 복사하지 않는 가장 큰 이유는 span 변수가 가리키는 인스턴스가 이전 또는 복사된 인스턴스가 될 것이다. 이 경우 하위 트리가 깊을 경우 직관적이지 못하다.
<div class="a">
<span></span>
</div>
<div class="b"></div>
const span = document.querySelector(‘span’);
const divB = document.querySelector(‘.b’);
divB.appendChild(span);
<div class="a"></div>
<div class="b">
<span></span>
</div>
https://indepth.dev/posts/1161/here-is-why-appendchild-moves-a-dom-node-between-parents