- 돔 트리의 구조
-
DOM 트리는 현재의 웹문서에 포함된 <body> 및 여타 문서 내 모든 컨텐츠들을 계층 구조로
나타내는데, document 객체를 루트로 하여 <html> 아래 <head> & <body>,
그 아래 요소 노드 및 텍스트 노드, 공백 노드 등으로 구성된다.
DOM 트리의 각 구성 요소는 Node 객체가 되며,
노드.
속성, 노드.메서드();로 접근할 수 있다 - DOM 트리 안의 Node 객체들에는 html 요소 노드 Element 객체 및 그에 딸린 텍스트 노드(html tag 내 텍스트)와 빈 노드(연속된 공백, 탭, 줄 바꿈), 속성 노드(html tag의 속성), 주석 노드 등이 있다
-
NodeList 객체는 일반적으로 document.
querySelectorAll();등의 메서드나 부모요소.children과 같은 속성들에 의해 반환되는 노드 컬렉션으로서 유사배열 객체이다 ← 예컨대, 부모요소.children에서 각 자식요소들은 배열에서와 같은 방식으로 접근할 수 있다!
html 문서 전체는 document 객체로 가져온다.
예컨데, document.title은 웹 문서 및 탭의 제목을 가리키는데,
그때 그때 새로운 메시지 등을 알리는데 사용할 수 있다
←
이 문단에 마우스를 올리고 브라우저 창 제목표시줄의 현재 탭 제목을 보세요..
const doc_title= document.title // 현재 문서의 제목을 변수로 저장한다
document.querySelector('#title_change').addEventListener('mouseenter', () => document.title='다시 오셨네요 ^^'); // 마우스를 올리면; 문서 타이틀을 변경한다
document.querySelector('#title_change').addEventListener('mouseleave', () => document.title= doc_title); // 마우스를 내리면; 다시 원래 제목을 넣어준다
(빈 노드)<p class="속성노드">텍스트 영역</p>(빈 노드)
☞
여기서 <p> 태그 영역 전체는 p 요소노드가 되며, 그 내부의 class="속성노드"
부분은 속성노드, 텍스트 영역 부분은 텍스트노드가 된다
←
<p> 태그 내부의 시작 및 끝 부분 공백은 제외되고,
각 태그 앞/뒤의 연속적인 공백 문자는 '빈 노드'로 생성된다!
* cf) 노드는 DOM 트리의 계층구조상 지위만 아니라, 다른 노드를 기준으로 하는 상대적 위치로도 참조된다. 우선, Root 는 DOM 트리의 최상위 노드를 말하는데, html 문서에서의 최상위 노드는 언제나 html 노드이다. Child 는 현재 노드 밑 단계에 속한 노드들(= 자식요소들)을, Parent 는 현재 노드를 포함하고 있는 상위 노드(= 부모요소)를 가리킨다. 한편, Sibling 은 현재 노드와 같은 단계에 위치하는 노드들(= 형제요소들)을, Descendant 는 DOM 트리에서 하위 수준에 포함된 노드들(= 후손요소들)을 가리킨다
✓
각 요소들은 . 연산자에 의한 체인 연결로 참조할 수 있지만, 요소노드 사이에 있는
공백노드의 존재로 인해 다루기에 불편하다. 이에 공백노드를 제외한 요소만의 참조를 위한 속성도
준비되어 있지만(예컨대, 부모요소.children),
역시 불편하여 실상은 요소의 id 나 class 를 쓰게 된다!
const el= document.querySelector('#my_container')
for (const child of el.children) { // el 내부 모든 자식 요소들로 루프를 돈다 ← children은 (텍스트 노드 등은 제외하고)요소 노드만을 대상으로 한다!
console.log(child.tagName) // el에 포함된 모든 태그명을 출력한다
}
☞
NodeList 컬렉션은 유사배열 객체이므로 for 문, for .. of 문이나
forEach(); 메서드로 반복하거나, Array.from(); 같은 메서드를 써서
배열로 변환할 수도 있다. 당연히, entries();, values();,
keys(); 등의 메서드들도 사용할 수 있다!
* cf)
참고로, document.querySelectorAll();은 호출 시점에서의 정적 노드 리스트를
가져오는 반면, 부모요소.children은 돔의 변경 사항을 실시간으로 반영한다
←
따라서, 노드 리스트에서 순회하거나, 그 길이(length)를 가져와야 할 때는
이 점에 유의해야 한다!
- 돔 이벤트 호출: on 이벤트
-
이벤트명 앞에
on을 붙여 해당 이벤트를 호출한다: 이벤트 대상.onclick / onwheel / onscroll / onvisibilitychange;등.. ← 이벤트 제거는 이벤트 대상.onclick= null;
let time_pic= document.querySelector('#on_click_button')
function cPic() { // 이벤트 처리함수
let d= new Date();
alert("현재 시각: " + d.toLocaleString())
}
time_pic.onclick= cPic // Click 이벤트로 cPic() 함수를 호출한다
☞ 이벤트 처리함수 호출 시에는 일반 함수 호출과는 달리 함수명 뒤에 ()를 붙이지 않는다 ← 뒤에 괄호를 붙이게 되면; 이벤트 호출 버튼을 클릭하기 전에 먼저 함수 코드가 실행되어버린다!
* cf)
최근에는 이 on 이벤트보다는 이벤트 리스너를 쓰는 것이 보편적이다.
addEventListener();는 같은 리스너에 대해
다수의 핸들러 함수를 등록할 수 있다는 점, 제거 시에도 짝이 되는
removeEventListener();가 존재한다는 점 등에서 on 이벤트에 비해 보다 유용하다!