본문 바로가기

개념정리/기술면접대비

[JS 기초탄탄 프로젝트] 브라우저 이해하기 - 문서, 이벤트, 인터페이스

참고

https://ko.javascript.info/ui

 

브라우저: 문서, 이벤트, 인터페이스

 

ko.javascript.info


1. 호스트 

자바스크립트가 돌아가는 환경. 옛날에는 웹브라우저만 존재했지만 오늘날에는 Node.js 기반의 서버를 비롯해 다양한 범용 어플리케이션이 될 수 있다. 플랫폼 특정 기능은 브라우저일 경우 웹페이지 제어수단, node일 경우는 서버 사이드 기능 등이 있다.

 

2. 브라우저 환경

호스트가 웹브라우저일 때 사용 가능한 최상단의 기능은 winodw 객체이다. (DOM, BOM, JS를 포함한다)

window 객체는 자바스크립트 코드의 전역 객체가 되며, 브라우저(호스트)를 제어할 수 있는 기능을 제공한다.

 

3. DOM

문서객체모델. 웹 페이지 내 콘텐츠를 객체화한 것. window객체에 포함된다.

문서 구조, 조작, 이벤트를 담당한다. 

 * 렌더링 엔진을 살펴볼 때 언급했듯이 css 스타일시트가 파싱된 객체는 DOM에 포함되지 않는다. CSSOM이라는 CSS 객체 모델이 따로 존재한다.

 

모든 html 태그는 DOM 노드가 되어 DOM트리를 구축한다.

html 문서의 주석도 DOM 트리에 주석노드로 추가된다. DOM 노드의 종류는 총 12가지이다.

 

html 문서의 오류는 브라우저가 자동교정한다.

html 명세에 따르면 모든 컨텐츠는 body 태그 내부에 존재하므로 </body> 뒤에 있는 컨텐츠는 자동으로 안으로 옮겨진다. 필수 태그 (html, head, body)나 여러 닫는 태그가 누락되었을 때도 자동으로 추가한다.

 

4. BOM

브라우저 객체 모델. window 객체에 포함된다.

문서 의외의 모든 것을 제어하기 위해 호스트(브라우저)가 제공하는 기능. 현재 URL을 알려주는 location 은 대표적인 BOM 객체이다.

 

5. 노드와 요소

모든 DOM객체는 자바스크립트를 통해 접근 및 제어가 가능하다.

DOM객체의 최상위 노드는 document 객체이다. 다음은 대표적인 노드의 접근방식.

<html> = document.documentElement

<head> = document.head

<body> = document.body

* document.body를 참조하는 시점에 html문서의 상태에 주의할 것. 현재 실행중인 script 태그 이하의 컨텐츠는 dom트리를 구축하지 못 하였으므로 해당 시점에 존재하지 않음. 

 

자식 노드, 자식 요소(element) 

node.childNodes, firstChild, lastChild : text 및 주석 노드 포함

node.children : 요소 노드만 추출

자식 노드 이하의 노드까지 포함하는 후손노드는 node.querySelectorAll("*") 로 추출 가능. 

이 때, 배열형으로 보이는 DOM 노드의 집합체는 모두 유사 배열 객체인 collection이다.

배열 메서드 대신 iterator 메서드(for ... of ... ) 사용 가능(for ... in은 사용하지 말 것!)하며 DOM 컬렉션은 읽기 전용이므로 값을 수정하고자 한다면 다른 메서드를 사용해야 함.

 

형제노드

같은 부모를 가진 노드들 

node.previousSibling, node.nextSibling : text 및 주석 노드 포함

node.previousElementSibling, node.nextElementSibling : 요소 노드만 추출

 

부모노드

node.parentNode (text 및 주석 노드 포함), node.parentElement (요소 노드만 추출)

*domumentElement (html)의 parentNode는 document 이지만 parentElement는 null이다.

 

테이블 요소 살펴보기 https://ko.javascript.info/dom-navigation#dom-navigation-tables

 

6. 요소 검색

document.getElementById("id") : id로 검색

node.querySelectorAll("선택자") : 기준 노드의 자식 요소 중 css선택자에 대응하는 모든 요소 반환

ex) node.querySelectorAll('ul > li:last-child');

node.querySelector("선택자") : 기준 노드의 자식 요소 중 css선택자에 대응하는 첫 번째 요소 반환

node.closest("선택자") : 기준 노드를 포함하며 css선택자에 대응하는 가장 가까운 조상 요소 반환

그 외 getElementsBy~~ 등은 모두 querySelectorAll로 대체 가능함.

둘의 차이점 : 동적으로 변화를 감지하는가(getElements~) 정적으로 변하지 않는가(querySelectorAll) 

 

7. 요소 판별

node.matches("선택자") : 기준 노드가 css선택자와 일치 여부 판별. Boolean 값 반환

ex) node.matches('a[href$="zip"]')

node1.contains(node2) : node2가 node1 에 속하거나 같은지 판별. Boolean 값 반환 

node.tagName | node.nodeName : 요소 | 노드의 태그 이름을 반환

 

8. DOM 내장 클래스

최상단의 EventTarget 은 추상 클래스. DOM 노드가 이를 상속받아 이벤트를 사용

EventTarget > Node > (Text), Elements, (Comment) > HTMLElment >  ...의 상속을 거쳐 요소들은 상속받은 모든 객체의 프로퍼티와 메서드를 사용 가능함.

*document 객체는 Node > Document > HTMLDocument 클래스를 상속받음

 

9. 요소 내용 추출 및 변경

innerHTML : 요소 안의 html을 문자열 형태로 받음

변경 node.innerHTML = "<div>새로운 내용</div>"

추가 node.innerHTML += "<div>새로운 내용</div>"

*추가는 기존 내용에 대한 변경 없이 추가만 하는 것 처럼 보이지만 사실상 아니다! 기존 내용에 새로운 내용을 더한 내용을 처음부터 다시 쓴다. 따라서 기존의 리소스가 전부 다시 로딩됨을 주의

 

outerHTML : 요소의 전체 html을 문자열로 받음. 이 또한 변경 가능.

하지만 이전의 값을 저장한 변수가 변경 값으로 자동 갱신되지 않음을 주의.

 

textContent : 기준 노드의 자식 노드 중 태그를 제외한 순수 텍스트만 추출 또는 변경.

innerHTHML 등으로 의도치 않은 html 태그의 삽입을 방지하려면 textContent을 사용할 것

 

 

10. 주요 프로퍼티

hidden : 요소를 숨김. style="dispaly:none" 과 동일함.

ex) <div hidden> 숨겨진 내용 </div> 또는 <div style="display:none"> 숨겨진 내용 </div>

스크립트 단에서 node.hidden = true || false ; 로 할당 가능.

value : input, select, textarea 태그에서 값을 저장하는 프로퍼티

href : a태그의 링크값

 

11. 비표준 속성

node.hasAttribute(name) : 속성 존재 확인

node.getAttribute(name) : 속성값 추출

node.setAttribute(name, value) : 속성값 변경

node.removeAttribute(name) : 속성 삭제

node.attributes : 모든 속성값의 name,vlaue 컬렉션 반환

 

12. 속성과 프로퍼티

node.프로퍼티 , node.getAttribute(속성) 서로 다를 수 있다. 

ex) href 값의 프로퍼티는 전체 url을, 속성은 할당된 값만을 반환함

 

13. dataset

비표준 속성을 안전하게 사용하기 위한 방법 (추후에 표준 프로퍼티로 등록되어서 덮어쓰이는 걸 방지)

data-속성명="값" 의 형태로 등록, node.dataset.속성명 으로 추출 

* 이 때 하이픈 속성명은 카멜 표기로 변환됨

ex) <div data-type="new">내용</div>

 

14. 노드 생성, 삽입, 삭제

document.createElement(tag) : 요소 노드 생성

document.createTextNode(text) : 텍스트 노드 생성

 

요소 노드를 생성하고 속성과 내용을 채워넣기

// 1. 요소 생성
let elem = document.createElement(tag);
// 2. 프로퍼티 추가 
elem.className = "some-class";
// 3. 내용 추가
elem.innerHTML = "<strong> 이것은 </strong> 추가된 요소이다";

 

문서에 삽입하기 ver.1

node.append(노드||문자열) : 기준 노드의 자식 노드 중 가장 뒤에 삽입

node.prepend(노드||문자열) : 기준 노드의 자식 노드 중 가장 앞에 삽입

node.before(노드||문자열) : 기준 노드의 앞에 삽입

node.after(노드||문자열) : 기준 노드의 뒤에 삽입

node.replacewith(노드||문자열) : 기준 노드를 새로운 내용으로 대체

* 주의사항! 이미 생성된 노드 또는 문자열을 전달. 문자열의 경우 html 태그도 순수 텍스트로 취급한다. 

* 복수 추가가 가능하다. 스프레드 연산자로 배열에 담긴 내용을 한번에 추가 가능

 

문서에 삽입하기 ver.2 

node.insertAdjacentHTML(where, html문자열) : html 태그를 포함한 문자열을 html로 삽입

where 의 포지션

beforebegin : 기준 노드의 앞에 

afterbegin : 기준 노드의 자식 노드 중 가장 앞에

beforeend : 기준 노드의 자식 노드 중 가장 뒤에

afterend : 기준 노드의 뒤에

*insertAdjacentText, insertAdjacentElement 는 잘 사용하지 않는다. ver.1의 방식으로 대체 가능하기 때문

 

node.remove() : 기준 노드를 삭제

 

15. 노드 복제

node.cloneNode(deep) : 기준 노드를 복제, deep은 boolean 값

(true- 기준 노드의 후손노드까지 깊은복제, false-후손노드 없이 기준 노드만)