게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌13 - JavaScript - 8년 전 등록 / 7년 전 수정

Document 객체

이번 시간에는 지난 시간 Window 객체에 이어 Document 객체에 대해 소개하겠습니다. 따로 강좌를 뺄 만큼 내용이 많습니다.

Document

지난 시간에 윈도우 객체를 window로 접근했죠. document도 윈도우 객체의 속성이기 때문에 window.document 이렇게 접근해야합니다. 하지만 window는 생략 가능(전역 객체)하기 때문에 그냥 document로 접근하면 되겠습니다. 역시 콘솔에 document하고 점을 쳐보면 수 많은 속성과 메소드들을 보실 수 있습니다.

window 객체 때 했던 것처럼 document 객체에서도 자주 쓰이는 것만 집어드리겠습니다. document는 html에 관한 것들을 담당하는 객체이니만큼 대부분의 것들이 태그를 선택하고 조작하는 데 사용됩니다.

document.getElementById(아이디)

html에서 해당 아이디를 가진 태그를 선택합니다.

document.getElementById('app-root'); // <div id="app-root" data-reactid="32">...</div>

document.getElementsByClassName(클래스), document.getElementsByName(이름), document.getElementsByTagName(태그)

html에서 각각 해당 클래스, 네임, 태그명을 가진 태그를 선택합니다. 여러개 선택되기 때문에 항상 배열입니다. 메소드 이름도 Elements입니다.

document.getElementsByTagName('nav'); // [<nav class="pTYnty2zkYzsdEoN1fhmO" data-reactid="8">…</nav>]

document.querySelector(선택자), document.querySelectorAll(선택자)

css 선택자로 선택할 수 있게 해줍니다. 아이디는 #, 클래스는 .(점)입니다. 태그명[속성명=속성값] 같은 것도 할 수 있고, 부모 > 자식, 부모 자손 등등 css의 선택자는 거의 다 쓸 수 있습니다. 위의 메소드보다 이 메소드를 더 많이 쓰게 될 겁니다.

document.querySelector('#app-root'); // <div id="app-root" data-reactid="32">...</div>

document.createElement(태그명)

document에 새로운 태그를 만들 때 사용합니다. 만든다고 바로 생기는 게 아니라 변수를 통해 메모리에 저장됩니다. 만든 태그를 추가하는 메소드는 따로 있습니다. 다음 시간에 알려드리겠습니다.

var div = document.createElement('div'); // 메모리에 div가 생성됨

document.createTextNode(텍스트);

텍스트도 하나의 요소입니다. 텍스트를 따로 만들 수 있습니다. 여기서 Node는 태그와 텍스트를 가리키는 명칭입니다. 역시 바로 생기는 게 아니라 변수를 통해 메모리에 저장됩니다.

var text = document.createTextNode('텍스트');

document.createDocumentFragment()

가짜 document를 만듭니다. 왜 이게 중요하냐면 자바스크립트로 document의 태그를 조작하는 것은 매우 성능이 떨어집니다. 특히 여러 태그를 반복문을 통해 동시에 추가할 때는요. 이럴 때 미리 가짜 document를 만들어서 여기에 추가를 한 후, 한 번에 document에 추가합니다. 이러면 진짜 document는 한 번만 조작하면 돼서 성능에 부담이 덜합니다.

간단하게 미리 보여드리겠습니다. 다음 시간에 다루겠지만 appendChild 메소드가 바로 추가하는 코드입니다.

var div = document.createElement('div');
var text = document.createTextNode('텍스트');
var fragment = document.createDocumentFragment();
div.appendChild(text);
fragment.appendChild(div);
document.body.appendChild(fragment);

div에 text를 담고, 그것을 fragment에 담은 후 최종적으로 body에는 fragment를 담았습니다. 직접적으로 body에 영향을 주는 것은 fragment를 추가할 때, 단 한 번입니다. 만약 appendChild같은 조작을 많이 해야할 경우, fragment에다가 한 후에 마지막에 fragment를 추가하면 됩니다.

document.head, document.body

각각 html의 head와 body에 접근할 수 있게 해줍니다.

document.anchors, document.links, document.forms, document.images, document.scripts

이름처럼 각각 모든 html 앵커, 링크, 폼, 이미지, 스크립트에 접근할 수 있게 해줍니다.

document.title

문서의 제목에 접근 가능합니다. 바꿀 수도 있고요. 문서의 제목은 바로 탭에 써 있는 글자입니다!

document.title = '여길 보세요';

위를 보면 바뀌었죠?

다음 강좌에는 document로 선택한 태그들에 관한 얘기(DOM)를 해보겠습니다!

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

8개의 댓글이 있습니다.
4년 전
프로젝트를 jquery안쓰고 javascript트로만 하고있는데요
그냥 자바스크립트에서 특정 인풋태그의 포커스 상태를 확인하고 싶은데 어떻게 하면되나요?
4년 전
👍
5년 전
console.log(document);를 입력하면 ReferenceError: document is not defined 이러한 에러가 발생합니다 어떻게 해결할 수 있나요?
5년 전
스크립트를 바디에 넣어보세요.
5년 전
\u003cscript src="index.js">\u003c/script>로 넣은 상태입니다 ㅠㅠ vsc사용중인데 따로 설정해야하는 게 있는건가요?
5년 전
너무 잘 이해되는 글!
7년 전
document.createDocumentFragment() 사용 목적이 아래 이유 때문인가요?? 내용을 읽고 이렇게 이해했는데 맞나요??

//가짜 document
var fragment = document.createDocumentFragment();

//\u003cdiv>javascript\u003c/div> 5번 부르기
for (var i = 0; i \u003c 5; i++) {
var div = document.createElement('div');
var text = document.createTextNode('javascript');
div.appendChild(text);
fragment.appendChild(div);
}

document.body.appendChild(fragment); //진짜 document는 한번만 조작. 성능 부담 덜 됨.
7년 전
맞습니다~ 단순히 몇 번 조작하는 것으로는 성능 체감이 힘들지만 수 백, 수 천 번 반복되면 조금씩 차이가 납니다.
7년 전
윗부분에 오타발견했습니다.
documnet.getElementsByClassName(클래스)
도컴넷이라고 되어있네요~
7년 전
감사합니다~
7년 전
강좌 계속 잘 보고 있습니다

위에 가짜 document 생성하여 반복문으로 태그 형성시 효율성을 높이는 코딩을 말씀하신 부분중에 한번에 처리를 하도록 코딩하는 부분으로 테스트 코딩을 했는데 아래 처럼 코딩하면 맞게 한걸지요? 코드는 작동은 잘 됩니다


for (var i=0; i \u003c subjects.length; i++) {

trTag = document.createElement("tr");
test = document.createDocumentFragment(); // 추가

subject = subjects[i];

var child = subject.childNodes;

for (var j=0; j \u003c child.length; j++) {
if (child[j].nodeType == 1) {
tdTag = document.createElement("td");
var text = document.createTextNode(child[j].firstChild.nodeValue);
tdTag.appendChild(text);
trTag.appendChild(tdTag);
test.appendChild(trTag); // 추가
}
}
document.getElementById("resultDisplay").appendChild(test);
//document.getElementById("resultDisplay").appendChild(trTag);
}
7년 전
네 그렇게 하시면 됩니다!
7년 전
그런데 이 문구라면 어차피 반복문을 돌리는 횟수만큼 가짜를 만들고 그걸 다시 진짜에 대입해서 처리하는 동작이 반복되는 것이라 처리과정만 더 늘어난 것인데 이게 어떤 측면에서 '한번에 처리된 효율적 코딩' 이라는 것인지
잘 이해가 안됩니다

한번에 한다라는 강좌내용상에 부합되려면 반복문구로 만들어진 전체 태그를 변수에 저장해서 한번의 입력코드로 입력하는 식이 되어야 할텐데 그러려면 for문으로 만들어진 전체 태그를 for 문 밖에서 가짜를 만들어서 한번에 처리하는 방식으로 코딩이 되어야 하지 않는가요?
7년 전
아 반복문이 두 번 중첩되는 거네요. 조용남자님 말씀처럼 for문 밖에서 createDocumentFragement를 선언한 후에 for문 안에서 메모리 DOM에 appendTo로 붙여주셔야 합니다.
7년 전
수정해서 테스트 해봤는데 문제없이 작동합니다
감사합니다
8년 전
밑에서 두번째 예제 중 document.body.appendChild(fragment); 구문에서 에러가 납니다. 'Cannot read property 'appendChild' of null(...)' 원인이 궁금해요~~~
8년 전
어떤 브라우저 사용하시죠? document.body는 null이 될 수가 없는데요...