‘프론트엔드 개발자를 위한 자바스크립트 프로그래밍’ 책을 참고하여 정리합니다. 오류가 있다면 언제든지 댓글 남겨주세요.
목차
- 선택자 API
- querySelector() 메서드
- querySelectorAll() 메서드
- matchesSelector() 메서드
- 요소 간 이동
- HTML5
- 클래스 관련 추가사항
- getElementsByClassName() 메서드
- classList 프로퍼티 - 포커스 관리
- HTMLDocument의 변화
- readyState 프로퍼티
- 호환성 모드 - 문자셋 프로퍼티
- 커스텀 데이터 속성
- 마크업 삽입
- innerHTML
- outerHTML
- insertAdjacentHTML() 메서드
- 메모리와 성능 문제 - scrollIntoView() 메서드
- 전용 확장
- 문서모드
- children 프로퍼티
- contains() 메서드
- 마크업 삽입
- innerText 프로퍼티
- outerText 프로퍼티 - 스크롤
DOM은 그 자체로도 매우 잘 정의된 API이긴 하지만, 특정 브라우저 전용 방법으로 확장하여 기능을 추가할 때도 많다.
1. 선택자 API
- 자바스크립트 라이브러리 중에 가장 인기 있는 기능은 CSS 선택자로 패턴을 만들고 그에 맞는 DOM 요소를 선택하는 능력이다.
- 선택자 API는 CSS 쿼리에 대한 브라우저의 네이티브 지원으로 W3C에서 명세화를 시작햇다.
- 이 기능을 구현한 자바스크립트 라이브러리들은 모두 기초적인 CSS 파서를 직접 만들고, 기존의 DOM 메서드를 이용해 문서 노드를 이동하며 패턴에 일치하는 노드를 골라내는 방식을 사용했다.
querySelector()
querySelectorAll()
- Document 타입과 Element타입에서 사용가능하다.
1-1. querySelector() 메서드
- 매개변수로 CSS 쿼리를 받는다.
- 패턴에 일치하는 첫번째 자손 요소를 반환한다. 없으면 null
1 | // body 요소를 가져온다. |
1-2. querySelectorAll() 메서드
- querySelector()와 유사한데, 일치하는 노드 전체를 반환한다.
- 즉, HTMLCollection(live)이 아닌 NodeList(non-live), 정적 인스턴스를 반환한다. (유사배열 형태)
- 매개변수에는 여러 CSS 쿼리를 넣어도 된다.
"h1, h2, h3"
1-3. matchesSelector() 메서드 ( matches()로 변경됨 ) +
- 선택자 API 레벨2 명세
- 매개변수로 CSS 선택자를 받고 요소가 그에 일치하면 true, 일치하지 않으면 false
2. 요소 간 이동
- 버전 9 미만의 IE는 타 브라우저와 달리 요소 사이의 공백을 텍스트 노드로 반환하지 않는다.
- 이 때문에 childNodes나 firstChild 같은 프로퍼티를 사용할 때 차이가 발생한다.
- DOM 명세를 유지하면서 브라우저 사이의 차이를 극복하려는 노력으로 요소간 이동 명세에서는 새 프로퍼티 그룹을 정의햇다.
요소간 이동 API에서 추가된 새 프로퍼티들
childElementCount
: 자식 요소 숫자를 반환하되 텍스트 노드와 주석은 제외한다.firstElementChild
: 첫번째 자식 요소를 가리킨다.lastElementChild
: 마지막 자식 요소를 가리킨다.previousElementSibling
: 이전 형제 요소를 가리킨다.nextElementSibling
: 다음 형제 요소를 가리킨다.
3. HTML5
- 이전의 HTML 명세는 자바스크립트 인터페이스에 대해서는 간단히만 설명하고 마크업 언어에만 집중했으며 자바스크립트와의 연결은 DOM으로 미뤘다.
- HTML5 명세는 마크업 언어와 함께 사용하도록 디자인된 자바스크립트 API를 상세히 설명하고 정의한다.
3-1. 클래스 관련 추가사항
getElementsByClassName()
메서드
- 클래스 이름 문자열을 매개변수로 받는다.
- 반환값 : HTMLCollection (live)
- 호출한 요소의 자손만 쿼리하여 반환한다.
반환값이 살아있는 객체라서 생기는 이슈
1 | // HTMLCollection을 반환한다. |
HTMLCollection은 실시간으로 Node의 상태 변경을 반영한다. (live HTMLCollection)
실시간으로 Node의 상태 변경을 반영하기 때문에 loop가 필요한 경우 주의가 필요하다.
아래와 같은 방법으로 회피할 수 있다.
방법1 > 역방향으로 돌리기
1 | var elems = document.getElementsByClassName('red'); |
방법2 > none-live NodeList를 반환하는 querySelectorAll을 사용한다.
1 | // querySelectorAll는 Nodelist(non-live)를 반환한다. IE8+ |
classList 프로퍼티
- 클래스 이름을 조작할 때는
className
프로퍼티를 이용해 클래스 이름을 추가하거나 제거, 교체했다.- 한 요소에 클래스가 3가지가 적용되어 있을 경우 이름 변경에 불편함이 있다.
- classList 프로퍼티는 DOMTokenList란 새 컬렉션 타입의 인스턴스이다.
- 다른 DOM 컬렉션과 마찬가지로 length존재 item() 메서드나 대괄호 표기법을 통해 데이터를 갖고올 수 있다.
- 크롬과 파폭3.6이상 가능
DOMTokenList의 메서드
- add(value) : 주어진 문자열 값을 목록에 추가한다.
- contains(value) : 주어진 값이 목록에 존재하면 true, 그렇지 않으면 false
- remove(value) : 주어진 문자열 값을 목록에서 제거
- toggle(value) : 값이 목록에 존재하면 제거하고 그렇지 않으면 추가
3-2. 포커스 관리
- 어느 요소에 포커스가 있는지, 현재 문서에 포커스가 있는지 판단하는 능력은 웹 접근성에 대단히 중요.
document.activeElement
- 항상 현재 포커스를 가진 DOM 요소를 가리키는 포인터를 포함한다.
- 키보드 탭 키를 통한 포커스, focus() 메서드로 자동 포커스를 받는다.
document.hasFocus()
- 문서에 포커스가 있는지 나타내는 불리언 값을 반환한다.
3-3. HTMLDocument의 변화
readyState 프로퍼티
- readyState 프로퍼티에 가능한 값은 2가지 이다.
- loading
- complete
- 문서를 불러왔는지 확인하는 것
- 보통은 onload 이벤트 핸들러를 사용했다.
<head>
프로퍼티
document.head
로도<head>
요소 참조가 가능하다.- 크롬과 사파리 5 가능
3-4. 문자셋 프로퍼티
- 문서의 문자셋을 다루는 프로퍼티
document.charset
- 문서의 문자셋을 나타내며, 새 문자셋 지정도 가능
- 파폭, 사파리, 오페라, 크롬
document.defaultCharset
- 브라우저 및 시스템의 기본 설정에 따라 문서에 기본적으로 적용해야 할 문자셋을 나타낸다.
- IE, 사파리, 크롬
3-5. 커스텀 데이터 속성 data-
- HTML5 요소에서는 요소의 렌더링에 필요한 정보나 시맨틱 값이 아닌 데이터를 접두사 **data-**가 붙은 비표준 속성에 제공하도록 한다.
- data- 뒤에는 자유롭게 네이밍
- 요소의 dataset프로퍼티를 통해 접근할 수 있다.
- 이름-값 쌍으로 이루어진
DOMStringMap
인스턴스이다. - 커스텀 데이터 속성은 요소에 데이터를 연결해야 하지만 사용자에게는 보이고 싶지 않을 때 유용하다.
- 이 테크닉은 링크 추적, 매시업에서 페이지 각 부분의 식별자로 흔히 쓰인다.
3-6. 마크업 삽입
마크업이 포함된 콘텐츠를 추가하는 것은 크로스 스크립팅 공격(XSS: Cross-Site Scripting Attacks)에 취약하다.
innerHTML
- 읽기모드 : 요소와 주석, 텍스트 노드 등의 자식 노드를 모두 나타내는 HTML 표현을 반환한다.
- innerHTML이 어떤 텍스트를 반활할지는 브라우저마다 다르다.
- 쓰기모드 : 주어진 값을 바탕으로 새 DOM 서브트리를 만들어서 요소의 잣기 노드를 완전히 교체한다.
주어진 문자열을 DOM 서브트리로 파싱해 이미 존재하는 자식 노드를 모두 교체한다.
모든 요소가 innerHTML을 지원하지 않는다.
- col, colgroup, framset, head, html, style, table, tbody, thead, tfoot, tr, title도 지원하지 않는다.
outerHTML
- 읽기모드 : 호출한 HTML 요소를 자식 노드와 함께 반환
- 쓰기모드 : 주어진 HTML 문자열을 파싱하여 DOM 서브트리를 생성하고 호출한 노드 전체를 교환하다.
- 나머지 특징은 innerHTML과 동일
insertAdjacentHTML() 메서드
- 삽입할 위치와 HTML 텍스트 두 가지를 매개변수로 받는다.
삽입할 위치 매개변수
beforebegin
: 호출한 요소 바로 앞에 삽입afterbegin
: 호출한 요소 첫번째 자식 요소 바로 앞에 삽입beforeend
: 호출한 요소 마지막 자식 요소 바로 다음에 삽입afterend
: 호출한 요소 바로 다음에 삽입
메모리와 성능 문제
- 위의 메서드들로 자식 노드를 교체하면 메모리에 문제가 생길 수 있는데 IE가 특히 심하다.
문제가 발생하는 지점 - 제거한 서브트리 요소에 이벤트 핸들러나 기타 자바스크립트 객체가 할당되어 있을 때
- 위의 상태에서 해당 핸들러나 프로퍼티를 사용하여 요소를 문서트리에서 제거한다면, 요소와 이벤트 핸들러 사이의 연결이 메모리에 남는다.
- 이른 작업이 계속되면 메모리 사용량이 점점 늘어난다.
- innerHTML, insertAdjacentHTML() 사용할 때는 제거할 요소의 이벤트 핸들러나 자바스크립트 객체 프로퍼티를 모두 제거하길 권한다.
3-7. scrollIntoView() 메서드
모든 HTML요소에 존재하며 브라우저 창이나 컨테이너 요소를 스크롤해서 해당 요소가 뷰포트에 보이게 한다.
- 매개변수로 true나 생략하면 창 전체를 스크롤하여 요소 상단과 뷰포트 상단을 맞춘다.
4. 전용 확장
- 문서모드
- children 프로퍼티
- contains() 메서드
- 마크업 삽입
- innerText 프로퍼티
- outerText 프로퍼티 - 스크롤