달력

11

« 2024/11 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

HTML을 객체 모델로 변환하여 반응성이 풍부한 인터랙티브 웹 페이지 만들기

developerWorks

 

JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.




난이도 : 초급

Brett McLaughlin, Author and Editor, O'Reilly Media Inc.

2006 년 3 월 14 일
2006 년 12 월 12 일 수정

프로그래머(백엔드 애플리케이션)와 웹 프로그래머(주로 HTML, CSS, JavaScript를 작성)사이에는 오래 전부터 엄격한 구분이 있었습니다. 하지만 Document Object Model (DOM)이 그 틈을 메우면서 백 엔드에서는 XML과, 프론트 엔드에서는 HTML과의 작업이 가능해 졌습니다.

시리즈 소개


많은 웹 프로그래머들과 마찬가지로 여러분도 HTML로 작업을 해봤을 것이다. HTML은 프로그래머들이 웹 페이지 상에서 작업할 때 사용한다. HTML은 애플리케이션이나 사이트를 마감하면서 수행하는 마지막 작업이고, 배치, 색상, 스타일 등을 끝까지 작업한다. 웹 페이지의 디자인과 공급과 관련한 프로세스를 명확히 파악할 필요가 있다.

  1. 누군가가(대개는 여러분이) 텍스트 에디터나 IDE에서 HTML을 만든다.
  2. 그런 다음, HTML을 Apache HTTPD 같은 웹 서버에 업로딩하고 이것을 인터넷이나 인트라넷에 퍼블리시 한다.
  3. 사용자는 Firefox 또는 Safari 같은 브라우저를 사용하여 웹 페이지에 요청한다.
  4. 사용자의 브라우저는 여러분의 웹 브라우저에 HTML용 요청을 만든다.
  5. 브라우저는 서버에서 받는 페이지를 그래픽 또는 테스트로 렌더링 한다. 사용자는 웹 페이지를 보고 활성화 한다.

매우 기본적인 것처럼 보이지만 실상은 매우 흥미롭다. 사실, 엄청난 양의 “성분(stuff)”들이 있다. 이것은 주로 4 단계와 5 단계 사이에 발생하고 바로, 이 부분을 이 글에서 중점적으로 다룰 것이다. 대부분의 프로그래머들은 사용자의 브라우저가 이것을 디스플레이 하도록 요청 받으면 대부분의 프로그래머들은 자신들의 마크업에 어떤 일이 발생하는지 정확히 고려하지 않기 때문이다.

  • 브라우저가 단순히 HTML에 있는 텍스트를 읽고 디스플레이 하는가?
  • CSS가 외부 파일에 있을 경우, CSS는 어떤가?
  • 외부 파일에 있는 JavaScript는 어떤가?
  • 브라우저는 이러한 아이템들을 어떻게 핸들하며 이벤트 핸들러, 기능, 스타일들을 텍스트 마크업으로 어떻게 매핑하는가?

이 모든 질문들에 대한 답은 Document Object Model이다. 이제 본격적으로 DOM을 논해보자.

웹 프로그래머와 마크업

프로그래머의 작업이 끝날 때 웹 브라우저가 시작된다. 다시 말해서, HTML 파일을 웹 서버 상의 디렉토리에 얹어 놓으면 보통 이것을 "완료된 것 "으로 정리해 놓고 절대로 다시는 생각하지 않는다! 깨끗하고, 구성이 잘된 페이지를 작성할 때도 이것은 너무 멋진 목표이다. 여러분의 마크업이 브라우저를 통해 다양한 버전의 CSS와 JavaScript로 디스플레이 하기를 원하는데 이것도 잘못은 아니다.

문제는 이러한 접근 방식이 브라우저에서 실제로 무슨 일이 일어나는지에 대해 프로그래머가 알 수 있는 범위를 제한한다는 점이다. 더욱이 클라이언트 측 JavaScript를 사용하여 웹 페이지를 동적으로 업데이트, 변경, 재구현 할 수 있는 기능 까지 제한한다. 이러한 한계를 제거하고 더 나아가 웹 사이트에서 더 나은 인터랙션과 생산성을 도모할 수 있다.

프로그래머가 하는 일

웹 프로그래머로서 여러분은 텍스트 에디터와 IDE를 시작하고 HTML, CSS, 심지어 JavaScript를 입력하기 시작한다. 태그, 셀렉터, 애트리뷰트를 사이트가 올바르게 보일 수 있도록 하는 작은 태스크라고 생각하기 쉽다. 하지만 그러한 관점을 좀더 확장 할 필요가 있다. 여러분이 콘텐트를 구성하고 있다는 것을 깨달아야 한다. 걱정하지 말라. 마크업의 가치에 대해 일장 연설을 늘어놓으려는 것은 아니다. 웹 페이지의 진정한 가치를 깨닫는 방법 내지는 형이상학적인 무엇인가를 설명하려는 것도 아니다. 여러분이 이해해야 할 것은 웹 개발 시 여러분의 역할이 정확히 무엇인가를 이해해야 한다.

페이지를 보이게 해야 하는 시점에 와서 여러분은 제안만 할 수 있을 뿐이다. 여러분이 CSS 스타일시트를 제공하면 사용자는 여러분의 스타일을 무시할 수 있다. 폰트 사이즈를 제공하면 사용자의 브라우저는 그러한 사이즈를 변경할 수 있고 모니터에 맞게 스케일링 할 수 있다. 폰트와 컬러도 사용자의 모니터에 맞게 선택할 수 있다. 페이지를 스타일링 할 때 최선을 다하는 것도 중요하지만 이는 웹 페이지에 큰 영향을 주지 못한다.

여러분이 완벽히 제어하는 것은 웹 페이지의 구조이다. 여러분의 마크업은 변경할 수 없고 사용자는 이것을 망칠 수 없다. 브라우저는 웹 서버에서 이것을 가져와서 디스플레이 한다. (여러분의 구미 보다 사용자의 구미에 따라 스타일로) 하지만 이 페이지의 구성은-이 단어가 그 문단 내에 있든 다른 div에 있든-전적으로 여러분에 달려있다. 페이지를 실제로 변경할 때(이것은 대부분의 Ajax 애플리케이션들이 집중하는 것이다.) 이것은 여러분이 운영하는 페이지의 구조이다. 텍스트의 조각의 색상을 변경하는 것이 좋지만 텍스트나 전체 섹션을 기존 페이지에 추가하는 것이 훨씬 더 좋다. 사용자가 그 섹션을 어떻게 스타일링 하던지 간에 페이지 그 자체의 구성을 가지고 작업한다.

마크업이 수행하는 일

마크업이 구성에 관한 것이라는 것을 깨달으면 이것을 달리 볼 수 있다. h1이 텍스트를 크고, 검고, 두껍게 만든다고 생각하는 대신 h1을 헤딩으로서 생각하라. 사용자가 어떻게 보는가, 그리고 사용자가 여러분의 CSS를 사용하는 자신들의 것을 사용하든 두 개를 결합하여 사용하든 이것은 두 번째 문제이다. 대신 마크업은 이 정도의 구성을 제공하는 것이라는 것을 깨달아라. P는 텍스트가 단락(paragraph)이라는 것을 나타내고, img는 이미지를, div는 페이지를 섹션으로 나눈다.

스타일과 작동(이벤트 핸들러와 JavaScript)가 fact 뒤에 이 구성에 적용된다는 것도 명확해 진다. 마크업은 적소에서 작동되거나 스타일링 되어야 한다. 따라서 HTML에 대한 외부 파일에 CSS를 갖는 것처럼 마크업의 구성도 스타일, 포맷팅, 작동과 분리된다. 엘리먼트의 스타일 또는 텍스트 조각을 JavaScript로부터 확실히 변화시킬 수 있고 마크업이 레이아웃 한 구성을 실제로 바꿀 수 있다는 것은 더 흥미 있는 사실이다.

마크업이 페이지에 구성 또는 프레임웍만 제공한다는 것을 마음에 새긴다면 본격적인 게임에 돌입해보자. 브라우저가 모든 텍스트 구성을 가지고, 이를 변경, 추가, 삭제 가능한 객체로 바꾸는 방법을 보자.

마크업에 대해 더 알아야 할 것들

플레인 텍스트 편집: 옳은가, 그른가?
플레인 텍스트 파일은 마크업을 저장하는 데는 이상적이지만 그 마크 업을 편집하는 데는 그렇지 못하다. Macromedia DreamWeaver 또는 Microsoft ® FrontPage ® 같은 IDE를 사용하는 것이 바람직하다. 이러한 환경은 종종 웹 페이지를 구현할 때 도움이 되는 지름길과 도움말을 제공한다. 특히 CSS와 JavaScript를 사용할 때 그렇다. 많은 사람들은 여전히 Notepad나 vi를 선호한다. (고백하건데 나도 그 중 하나이다.) 이것 역시 좋은 선택이다. 두 경우 모두 마지막 결과는 마크업으로 가득 찬 텍스트 파일이다.

네트워크를 통한 텍스트: 좋은 것
이미 언급했듯이 텍스트는 HTML이나 CSS 같은 문서에 있어 훌륭한 미디어이다. 이것은 네트워크를 통해 수백, 수천 번 이동한다. 브라우저가 텍스트를 나타내는데 어려움을 겪는다면 텍스트를 시각적 페이지와 그래픽 페이지로 변환한다는 의미이다. 브라우저가 웹 서버에서 페이지를 실제로 가져오는 방법과는 관련이 없다. 이 경우 텍스트는 여전히 최상의 옵션이다.

텍스트 마크업의 장점

웹 브라우저를 논하기 전에 왜 플레인 텍스트가 HTML을 저장하기에 최상의 선택인지를 생각해 봐야 한다. (마크업에 대해 더 알아야 할 것들 참조) 찬반을 논하기 전에, 페이지가 보여질 때 마다 HTML이 네트워크를 통해 웹 브라우저로 보내진다는 것을 생각해 보라. (캐싱 같은 문제는 차후에 논하기로 한다.) 텍스트와 함께 전달하는 것 보다 효율적인 방법은 없다. 바이너리 객체, 그래픽으로 구현된 페이지, 재구성된 마크업 청크 등, 이 모든 것들은 플레인 텍스트 파일 보다 네트워크를 통해 전송할 때 더 어려운 것들이다.

브라우저를 이러한 방정식에 대입해 보자. 오늘날의 브라우저에서는 사용자가 텍스트의 크기길 변경하고, 이미지를 스케일링 하고 CSS나 JavaScript를 다운로드 할 수 있다. 이 모든 것은 페이지의 온갖 종류의 그래픽 표현을 브라우저로 보내는 전조가 된다. 대신 브라우저는 미가공 HTML을 필요로 한다. 왜냐하면 이것은 태스크를 핸들하기 위해 서버를 믿기 보다 어떤 프로세싱이든 브라우저에 있는 페이지에 적용할 수 있기 때문이다. 같은 맥락에서, CSS와 JavaScript를 분리하고, 이들을 HTML 마크업에서 분리할 때에는 분리하기 쉬운 포맷이 필요하다.

HTML 4.01, XHTML 1.0/ 1.1 같은 새로운 표준들이 콘텐트(페이지의 데이터)를 표현과 스타일(보통 CSS에 의해 적용됨)에서 분리하겠다는 약속을 기억하는가? 프로그래머들이 CSS에서 HTML을 분리하려면 브라우저를 실행하여 페이지에서 몇몇 구현들을 가져오고 그러한 표준의 많은 장점들을 없앤다. 브라우저에서 이렇게 다른 부분들을 계속 분리시키면 브라우저는 서버에서 HTML을 가져올 때 최상의 유연성을 보인다.

웹 브라우저 분석

지금까지 여러분이 읽은 모든 것은 웹 개발 프로세스에서의 여러분의 역할에 대한 리뷰에 불과하다. 하지만 웹 브라우저가 무엇을 수행하는지를 논해야 하는 시점에서 유능한 많은 웹 디자이너와 개발자들은 보이지 않는 곳에서 실제로 어떤 일이 발생하는지 종종 깨닫지 못한다. 이 섹션에서는 바로 그 부분을 설명하도록 하겠다. 걱정하지 말라. 코드도 함께 등장할 것이다. 잠시 코딩하고 싶은 조바심을 접어두라. 웹 브라우저가 정확히 어떤 일을 수행하는지를 이해하는 것이 정확한 코딩 작업의 필수이기 때문이다.

텍스트 마크업의 단점

텍스트 마크업이 디자이너나 페이지 생성자에게 엄청난 이득을 주듯이 브라우저에는 비교적 큰 단점을 갖고 있다. 특히 브라우저는 텍스트 마크업을 사용자에게 시각적으로 직접 나타내기가 매우 힘들다. (마크업에 대해 더 알아야 할 것들 참조) 다음과 같은 브라우저 태스크를 생각해 보라.

  • CSS 스타일—외부 파일에 있는 다중 스타일시트—을 HTML 문서의 엘리먼트 유형, 클래스, 아이디, 위치에 기반하여 마크업에 적용한다.
  • JavaScript 코드에 기반한 스타일과 포맷팅—외부 파일에도 있음—을 HTML 문서의 다른 부분들에 적용한다.
  • JavaScript 코드에 기반하여 폼 필드의 값을 변경한다.
  • JavaScript 코드에 기반하여 이미지 롤오버와 이미지 스와핑 같은 시각 효과를 지원한다.

복잡함은 이러한 태스크들을 코딩 하는데 있는 것이 아니다. 이러한 일들을 하기는 정말 쉽다. 복잡함은 브라우저가 실제로 요청된 액션을 수행하는 데서 온다. 마크업이 텍스트로 저장되면 center-text 클래스에서 텍스트를 센터링 해야 한다. (text-align: center) 이것을 어떻게 할 것인가?

  • 텍스트에 인라인 스타일링을 추가하는가?
  • 브라우저의 HTML 텍스트에 스타일링을 적용하고 어떤 것이 센터링 되는지, 어떤 것이 센터링 되지 않는지를 지켜보는가?
  • 스타일링 되지 않은 HTML을 적용한 다음 팩트 다음에 포맷을 적용하는가?

이 같은 매우 어려운 질문들 때문에 몇몇 사람들이 오늘날 브라우저를 코딩을 한다.

확실히, 플레인 텍스트는 브라우저를 위해 HTML을 저장하는 최상의 방법은 아니다. 텍스트가 페이지의 마크업을 가져오는 좋은 솔루션이었지만 말이다. 이 외에도 JavaScript가 페이지의 구조를 변경하는 기능은 트릭이 조금 있다. 브라우저가 수정된 구조를 디스크에 재작성 해야 하는가? 문서의 현재 어떤 단계에 있는지를 어떻게 파악할 수 있는가?

확실히 텍스트는 답이 못 된다. 수정하기도 어렵고, 스타일과 작동을 추가하기에는 불편하고, 궁극적으로 오늘날 웹 페이지의 동적인 특징과 거리가 멀다.

트리 뷰로 이동하기

이 문제에 대한 답, 오늘날의 웹 브라우저에 맞는 답은 트리 구조를 사용하여 HTML을 나타내는 것이다. 텍스트 마크업으로 구현된 단순하고 지루한 HTML 페이지 대신 Listing 1을 보자.


Listing 1. 텍스트 마크업의 간단한 HTML 페이지
				
<html>
 <head>
  <title>Trees, trees, everywhere</title>
 </head>
 <body>
  <h1>Trees, trees, everywhere</h1>
  <p>Welcome to a <em>really</em> boring page.</p>
  <div>
    Come again soon.
    <img src="come-again.gif" />
  </div>
 </body>
</html>

그림 1. 이 브라우저는 이것을 트리 구조로 변환한다.


그림 1. Listing 1의 트리 뷰
The tree view of Listing 1

이 글을 위해 단순함을 유지했다. DOM과 XML 전문가는 공백이 문서에 있는 텍스트가 구현되고 웹 브라우저의 트리 구조에서 깨지는 방법에 영향을 줄 수 있다는 것을 알 것이다. 공백의 효과에 대해 알고 있다면 정말 대단하다. 그렇지 않다면 공부하면 된다. 걱정 말라. 이것이 문제가 될 때 필요한 것이 무엇인지를 깨닫게 될 것이다.

실제 트리 백그라운드 외에 여기에서 알아야 할 첫 번째 것은 트리에 있는 모든 것이 가장 바깥쪽에서 시작되고 HTML의 엘리먼트(html)를 포함하고 있다는 것이다. 이는 트리 메타포에서 루트(root) 엘리먼트라고 불린다. 이것이 트리의 바닥에 있지만 트리를 분석할 때면 언제나 이것부터 시작한다. 완전히 거꾸로 뒤집어보면 도움이 될 것이다.

루트에서부터 마크업의 다양한 조각들 간 관계를 보여주는 라인의 흐름을 따라가 보라. headbody 엘리먼트는 html 루트 엘리먼트의 자식들이다. titlehead의 자식이고 "Trees, trees, everywhere" 텍스트는 title의 자식이다. 전체 트리는 브라우저가 그림 1과 비슷한 구조가 될 때까지 이와 같이 구성된다.

몇 가지 추가 용어

트리 메타포를 이해하기 위해서 headbodyhtml의 브랜치(branch)라고도 일컬어진다. 이들은 자신들의 자식이 있기 때문에 브랜치이다. 트리의 말단에 다다르면 "Trees, trees, everywhere"와 "really" 같은 텍스트로 가게 된다. 이들은 자식들이 없기 때문에 잎(leave)으로 일컬어진다. 이 용어들을 다 기억할 필요는 없고 특정 용어가 무엇을 의미하는지를 파악하려면 나무의 구조를 머리속에 그려보면 된다.

객체의 가치

기본적인 용어들을 익혔으니 엘리먼트 이름과 텍스트가 들어있는 작은 직사각형에 집중해 보자.(그림 1) 각 직사각형들은 객체이다. 여기에서 브라우저는 텍스트와 관련된 문제들을 해결한다. 객체를 사용하여 HTML 문서의 조각들을 나타냄으로서 구성을 변경하고, 스타일을 적용하며, JavaScript를 문서에 액세스 시키기가 매우 쉬워진다.

객체 유형과 속성

모든 가능한 유형의 마크업은 고유의 객체 유형을 갖는다. 예를 들어, HTML에 있는 엘리먼트는 Element 객체 유형에 의해 구현된다. 문서에 있는 텍스트는 Text 유형에 의해 구현된다. 애트리뷰트는 Attribute 유형에 의해 표현된다.

따라서 웹 브라우저는 객체 모델을 사용하여 문서를 표현하고—정적 텍스트를 다룰 필요가 없음—객체 유형에 따라 즉각 구분할 수 있다. HTML 문서는 파싱되고 그림 1의 객체들로 바뀐다. 그런 다음 대괄호 같은 이스케이프 시퀀스로 바뀐다. 이는 브라우저의 작업을 훨씬 쉽게 만든다. 적어도 인풋 HTML을 파싱한 후에도 말이다. 어떤 것이 엘리먼트이고 어떤 것이 애트리뷰트인지 파악하고 객체 유형을 어떻게 다룰지를 결정하는 작동은 간단하다.

객체들을 사용함으로서 웹 브라우저는 그러한 객체들의 속성들을 변경할 수 있다. 예를 들어, 각 엘리먼트 객체는 하나의 부모와 자식 리스트를 갖고 있다. 새로운 자식 엘리먼트나 텍스트를 추가하는 것은 새로운 자식을 엘리먼트의 자식 리스트에 추가하는 문제에 지나지 않는다. 이러한 객체들은 또한 style 속성을 갖고 있어서 엘리먼트의 스타일이나 텍스트 조각을 쉽게 변경할 수 있다. 예를 들어, 다음과 같이 JavaScript를 사용하여 div의 높이를 수정할 수 있다.

someDiv.style.height = "300px";

다시 말해서, 웹 브라우저는 이와 같이 객체 속성들을 사용하여 트리의 모양과 구조를 쉽게 변경한다. 이것을 복잡한 것과 비교해 보라. 속성과 구조가 변할 때 마다 브라우저는 정적 파일을 재작성 하고, 재 파싱 하고 이를 스크린에 다시 디스플레이 해야 한다. 이 모든 것이 객체로도 가능해진다.

이 시점에서 HTML 문서에 대해 알아보고 이를 트리로 그려보자. 평범한 요청은 아닌 것 같지만 이들을 다룰 수 있으려면 이러한 트리 구조에 익숙해져야 한다. 보통의 요청은 아닌 것 같지만 이 트리 구조에 익숙해져야 한다. 이들을 조작할 수 있으려면 말이다.

이 프로세스에서 몇 가지 이상한 점들을 발견하게 된다. 다음과 같은 상황을 생각해 보자.

  • 애트리뷰트에는 어떤 일이 발생하는가?
  • emb 같은 엘리먼트로 나뉜 텍스트는 어떻게 되는가?
  • 정확하게 구축되지 않은 HTML은 어떻게 되는가? (닫기 p 태그가 소실 되는 경우)

일단 이러한 유형의 문제에 익숙해지면 다음 섹션을 이해하기가 더 쉬울 것이다.

엄격함을 유지한다.

내가 언급했던 것을 직접 해본다면 마크업의 트리 뷰에 잠재적 문제 몇 가지들을 발견할 것이다. (직접 하지 않을 것이라면 내 말을 믿어라.) 사실, Listing 1그림 1에서 여러 가지를 발견할 것이다. p 엘리먼트가 나뉘어지는 방법부터 시작해서 말이다. 전형적인 웹 개발자에게 p 엘리먼트의 텍스트 콘텐트가 무엇인지를 묻는다면 일반적으로 "Welcome to a really boring Web page"라고 답할 것이다. 이것을 그림 1과 비교하면 이러한 대답이 논리적이긴 하지만 전혀 맞지 않다는 것을 알게 될 것이다.

p 엘리먼트는 세 개의 다른 자식 객체들을 갖고 있고, 이 중 어떤 것도 전체 "Welcome to a really boring Web page" 텍스트를 포함하고 있지 않다. "Welcome to a "와 " boring Web page" 같은 텍스트의 일부를 볼 수는 있어도 이것이 전체 문장은 아니다. 이를 이해하려면 마크업의 모든 것이 어떤 유형의 객체로 바뀌어야 한다는 것을 기억하라.

더욱이 순서도 문제가 된다. 정확한 마크업이지만 여러분의 HTML에서 제공된 순서와 다르다면 사용자가 웹 브라우저에 어떻게 대응할지를 상상할 수 있겠는가? 문서를 구성했던 방식이 아닐 때에도 제목과 헤딩 사이에 끼게 될 것이다. 브라우저는 엘리먼트와 텍스트의 순서를 보존해야 한다.

이 경우, p 엘리먼트는 세 개의 구별된 부분들을 갖는다.

  • em 엘리먼트 앞에 오는 텍스트
  • em 엘리먼트
  • em 엘리먼트 뒤에 오는 텍스트

이 순서를 섞는다면 텍스트의 잘못된 부분에 강조를 적용한 것이다. 이 모든 것을 바로잡으려면 p 엘리먼트는 Listing 1의 HTML에 나타났던 순서 대로 세 개의 객체 자식들을 가져야 한다. 더욱이 강조된 텍스트인 "really"는 p의 자식 엘리먼트가 아니다. 이것은 p의 자식인 em의 자식이다.

이 개념을 이해하는 것은 매우 중요하다. "really" 텍스트가 나머지 p 엘리먼트의 텍스트와 함께 디스플레이 되더라도 이것은 여전히 em 엘리먼트의 직접적인 자식이다. 이것은 나머지 p와는 다른 포맷팅을 가질 수 있고 나머지 텍스트와 개별적으로 움직일 수 있다.

이를 유념하면서 Listing 23의 HTML을 다이어그램으로 그리면서 텍스트에 정확한 부모를 유지하도록 한다. 정확한 부모로 유지시킨다.


Listing 2. 약간의 트릭이 들어간 엘리먼트 중첩이 있는 마크업
				
<html>
 <head>
  <title>This is a little tricky</title>
 </head>
 <body>
  <h1>Pay <u>close</u> attention, OK?</h1>
  <div>
   <p>This p really isn't <em>necessary</em>, but it makes the 
      <span id="bold-text">structure <i>and</i> the organization</span>
      of the page easier to keep up with.</p>
  </div>
 </body>
</html>


Listing 3. 보다 트릭이 심한 엘리먼트의 중첩
				
<html>
 <head>
  <title>Trickier nesting, still</title>
 </head>
 <body>
  <div id="main-body">
   <div id="contents">
    <table> 
     <tr><th>Steps</th><th>Process</th></tr>
     <tr><td>1</td><td>Figure out the <em>root element</em>.</td></tr>
     <tr><td>2</td><td>Deal with the <span id="code">head</span> first,
         as it's usually easy.</td></tr>
     <tr><td>3</td><td>Work through the <span id="code">body</span>.
         Just <em>take your time</em>.</td></tr>
    </table>
   </div>
   <div id="closing">
    This link is <em>not</em> active, but if it were, the answers
    to this <a href="answers.html"><img src="exercise.gif" /></a> would
    be there. But <em>do the exercise anyway!</em>
   </div>
  </div>
 </body>
</html>

이러한 관행에 대한 해답은 이 글 끝부분의 GIF 파일인 tricky-solution.gif (그림 2)trickier-solution.gif (그림 3)에서 찾을 수 있다. 스스로 알아내기 전에 몰래 보지 않기를 바란다. 엄격한 규칙이 트리를 구성하는데 어떻게 적용되는지를 이해하면 도움이 될 것이다. HTML과 트리 구조를 마스터 한다면 정말로 도움이 될 것이다.

애트리뷰트

애트리뷰트를 어떻게 다루어야 하는지를 파악할 때 문제가 생긴 적이 있는가? 앞서 언급했지만 애트리뷰트는 고유의 객체 유형을 갖고 있지만 애트리뷰트는 엘리먼트의 자식이 아니다. 중첩 엘리먼트와 텍스트는 같은 레벨의 애트리뷰트가 아니고 Listing 23에 대한 답에는 애트리뷰트가 나타나지 않는다는 것을 알 수 있다.

사실 애트리뷰트는 브라우저가 사용하는 객체 모델에 저장되지만 이들은 특별한 경우이다. 각 엘리먼트는 여기에 사용되는 애트리뷰트 리스트를 갖고 있고 자식 객체의 리스트에서 분리된다. 따라서 div 엘리먼트는 "id" 애트리뷰트와 또 다른 이름 " class "를 포함하고 있는 리스트를 갖게 된다.

엘리먼트용 애트리뷰트가 유일한 이름을 갖고 있어야 한다는 것을 기억하라. 다시 말해서, 하나의 엘리먼트가 두 개의 "id" 또는 두 개의 "class"애트리뷰트를 가질 수 없다. 보존하고 액세스 할 리스트를 매우 쉽게 만든다. 다음 글에서 보겠지만 getAttribute("id") 같은 메소드를 호출하여 애트리뷰트 값을 이름 별로 얻을 수 있다. 애트리뷰트를 추가하고 기존 애트리뷰트의 값을 비슷한 메소드 호출을 설정(재설정)할 수 있다.

애트리뷰트의 독자성은 리스트를 자식 객체들의 리스트와 구별시킨다. p 엘리먼트는 그 안에 여러 em 엘리먼트를 갖고 있기 때문에 자식 객체의 리스트에는 중복 아이템이 포함될 수 있다. 자식 리스트와 애트리뷰트 리스트는 비슷하게 작동하지만 하나는 중복을 포함할 수 있고(객체의 자식) 하나는 그럴 수 없다는 것이다. (엘리먼트 객체의 애트리뷰트) 마지막으로 엘리먼트만이 애트리뷰트를 가질 수 있기 때문에 텍스트 객체는 여기에 첨부될 리스트가 없다.

어지러운 HTML

더 진행하기에 앞서 브라우저가 마크업을 트리 구현으로 변환하는 방법, 브라우저가 엉성한 폼의 마크업을 어떻게 다루는지를 볼 필요가 있다. 구성이 잘되었다(Well-formed)는 용어는 XML에서 광범위하게 사용되고 두 가지 기본적인 의미가 있다.

  • 모든 오프닝 태그는 여기에 매칭되는 클로징 태그를 갖고 있다. 따라서 모든 <p></p><div></div>와 매칭된다.
  • 가장 안쪽의 오프닝 태그는 가장 안쪽의 클로징 태그와 매칭된다. 그 다음 안쪽의 오프닝 태그는 그 다음 안쪽의 클로징 태그와 매칭되는 식이다. 따라서 <b><i>bold and italics</b></i>는 옳지 않다. 가장 안쪽의 오프닝 태그인 <i><b>와는 맞지 않기 때문이다. 이를 잘 구성하려면 오프닝 태그 순서를 바꾸거나 클로징 태그 순서를 바꾼다. (둘 다 바꾼다면 똑 같은 문제가 생긴다.)

이 두 가지 규칙들을 자세히 연구해 보자. 두 규칙 모두 문서의 간단한 구성을 늘릴 뿐만 아니라 모호함을 제거한다. Bolding이 먼저 적용되고 그 다음에 italics를 적용해야 하는가? 아니면 그 반대인가? 순서와 다의성이 큰 문제인 것처럼 보이지만 CSS에서는 이 규칙들이 다른 규칙들을 무시할 수 있도록 한다. 따라서 b 엘리먼트 안에 있는 텍스트의 폰트가 i 엘리먼트 내의 폰트와 다르다면 포맷팅이 적용되는 순서는 매우 중요하다. 따라서 HTML 페이지의 좋은 구성이 중요한 것이다.

잘 구성되지 않은 문서를 브라우저가 받는 경우 할 수 있는 최선을 다한다. 결과 트리 구조는 가장 좋은 경우는 원래 페이지 작성자가 의도했던 것과 비슷한 것이고 최악의 경우 완전히 다른 것이다. 브라우저에 페이지를 로딩하고 기대했던 것과 완전히 다른 일이 발생한다면 구조에 대해 다시 생각해 봐야 한다. 물론 픽스는 간단하다. 문서가 잘 구성되었는지를 확인하는 것이다. 표준화된 HTML을 작성하는 방법을 모르겠다면 참고자료를 참조하라.

DOM

지금 까지, 브라우저가 웹 페이지를 객체 구현으로 변환하는 것에 대해 배웠다. 아마도 여러분은 객체 구현이 DOM 트리라고 생각해왔을 것이다. DOM은 문서 객체 모델(Document Object Model)을 의미하고 World Wide Web Consortium (W3C)에서 사용할 수 있는 스팩이다.(참고자료)

DOM은 브라우저가 마크업을 나타낼 수 있도록 하는 객체의 유형과 속성들을 정의한다. (다음 글에서는 JavaScript와 Ajax 코드에서 DOM을 사용하는 방법을 설명하겠다.)

문서 객체

무엇보다도 객체 모델에 액세스 해야 한다. 이것은 매우 쉽다. 웹 페이지에서 실행되는 JavaScript 코드 조각에 있는 빌트인 document 변수를 사용하려면 다음과 같이 코드를 작성한다.

var domTree = document;

물론 이 코드는 그 자체로는 쓸모가 없지만 모든 웹 브라우저가 document 객체를 JavaScript 코드에 사용할 수 있도록 하고 객체는 완벽한 마크업 트리를 나타낸다.(그림 1)

모든 것이 노드이다!

확실히, document 객체는 중요하지만 단지 시작에 불과하다. 더 진행하기 전에 또 다른 용어인 노드(node) 개념을 익혀야 한다. 마크업의 각 부분이 객체에 의해 구현되지만 이는 하나의 객체(특정 유형의 객체)인 DOM 노드에 불과하다는 것을 이미 알 것이다. 보다 특별한 유형인 텍스트, 엘리먼트, 애트리뷰트는 이러한 기본적인 노드 유형에서 확장된다. 따라서 여러분은 텍스트 노드, 엘리먼트 노드, 애트리뷰트 노드를 갖고 있는 것이다.

JavaScript로 프로그래밍을 했다면 DOM 코드를 사용하는 방법도 알 것이다. 이 Ajax 시리즈를 충실히 이행했다면 여러분도 DOM 코드를 사용한 것이다. 예를 들어, var number = document.getElementById("phone").value; 라인은 DOM을 사용하여 특정 엘리먼트를 찾아 그 엘리먼트의 값(이 경우 폼 필드)을 가져온다. 따라서 여러분이 인식 못했더라도 여러분은 document를 JavaScript 코드에 타이핑 할 때마다 DOM을 사용한 것이었다.

여러분이 배웠던 용어를 정비하기 위해 DOM 트리는 객체의 트리지만 보다 구체적으로는 노드 객체들의 트리이다. Ajax 애플리케이션 또는 JavaScript에서 그러한 노드들과 작업하여 엘리먼트와 이것의 콘텐트를 지우고 특정 텍스트 조각을 강조하고 새로운 이미지 엘리먼트를 추가하는 등 특별한 효과를 만들 수 있다. 이 모든 것은 클라이언트 측(웹 브라우저에서 실행되는 코드)에서 발생하기 때문에 이러한 효과는 서버와 통신 없이 즉시 발생한다. 결국 보다 반응성 있는 애플리케이션이 될 것이다.

대부분의 프로그래밍 언어에서 각 노드 유형에 맞는 실제 객체 이름들을 배우고 속성들을 배우고 유형과 캐스팅을 파악해야 한다. 하지만 이중 어떤 것도 JavaScript에서는 필요하지 않다. 변수를 만들어서 여기에 원하는 객체를 할당한다.

var domTree = document;
var phoneNumberElement = document.getElementById("phone");
var phoneNumber = phoneNumberElement.value;

변수를 만들고 여기에 정확한 유형을 핸들하는 유형과 JavaScript는 없다. 결과적으로 JavaScript에서 DOM을 사용하기가 매우 쉬워진다. (다음 글에서는 XML과 관련한 DOM에 초점을 맞춰 설명하겠다.)

결론

지금 여기에서 설명한 것이 DOM의 전부는 아니다. 사실 이 글은 DOM의 개요서에 지나지 않는다. 오늘 설명한 것 이상의 것이 DOM에는 있다.

다음 글에서는 JavaScript에서 DOM을 사용하여 웹 페이지를 만들고 HTML을 수정하고 사용자 인터랙션을 높이는 방법을 설명하겠다. DOM을 주제로 다시 한면 설명하겠다. Ajax 애플리케이션의 중요한 부분인 DOM에 익숙해지기 바란다.

바로 지금 DOM을 더 깊이 연구할 수 있다. DOM 트리로 옮기는 방법, 엘리먼트와 텍스트의 값을 얻는 방법, 노드 리스트를 통해 반복하는 방법 등을 자세히 설명하겠다.

무엇보다도 트리 구조에 대해 생각해 보고 HTML을 통해서 웹 브라우저가 HTML을 마크업의 트리 뷰로 어떻게 전환하는지에 대해 생각해 보고 다음 글에 임하기 바란다. 또한, DOM 트리의 구성을 생각해 보고 이 글에 설명된 특별한 경우를 생각해 보라. 애트리뷰트, 그 안에 엘리먼트와 혼합된 텍스트, 텍스트 콘텐트를 갖고 있지 않은 엘리먼트(img 엘리먼트) 등을 생각해 보라.

이러한 개념을 확실히 이해하고 JavaScript와 DOM의 신택스를 배운다면 도움이 될 것이다.

여기 Listing 22에 대한 답을 제시하겠다. 샘플 코드도 포함되어 있다.


그림 2. Listing 2에 대한 답
The answer to Listing 2

Figure 3. The answer to Listing 3
The answer to Listing 3

기사의 원문보기



참고자료

교육

제품 및 기술 얻기

토론


필자소개

Photo of Brett McLaughlin

Brett McLaughin은 Logo 시절부터 컴퓨터 업계에서 일했다 (작은 트라이앵글 기억하는가?). 최근에 그는 Java 및 XML 커뮤니티에서 인기 저자 및 프로그래머가 되었다. Nextel Communication사에서는 복잡한 기업 시스템 실행에 관한 업무, Lutris Technologies 사에선 애플리케이션 서버를 실지로 작성하는 업무, 최근 O’Reilly Media 사에서는 이와 관련된 중요한 책을 저술, 편집했다. Brett의 최근 저서인 Head Rush Ajax는 Ajax에 관한 혁신적인 연구에 기여, 공동 저자인 Eric 및 Beth Freeman과 함께 공동으로 수상했다. 그의 최근 저서인 Java 1.5 Tiger: A Developer's Notebook은 신 자바 기술 버전 상에서 이용 가능한 첫 번째 저서다. Brett의 최신 Java 및 XML은 자바 언어에서 XML 기술을 활용한 명백한 업적 중 하나로 남아 있다.

:
Posted by 뽀기