Ajax 마스터하기, Part 4: 웹 응답에 DOM 활용하기 그거/Java2007. 1. 29. 14:33
HTML을 객체 모델로 변환하여 반응성이 풍부한 인터랙티브 웹 페이지 만들기 |
난이도 : 초급 Brett McLaughlin, Author and Editor, O'Reilly Media Inc. 2006 년 3 월 14 일 프로그래머(백엔드 애플리케이션)와 웹 프로그래머(주로 HTML, CSS, JavaScript를 작성)사이에는 오래 전부터 엄격한 구분이 있었습니다. 하지만 Document Object Model (DOM)이 그 틈을 메우면서 백 엔드에서는 XML과, 프론트 엔드에서는 HTML과의 작업이 가능해 졌습니다.
많은 웹 프로그래머들과 마찬가지로 여러분도 HTML로 작업을 해봤을 것이다. HTML은 프로그래머들이 웹 페이지 상에서 작업할 때 사용한다. HTML은 애플리케이션이나 사이트를 마감하면서 수행하는 마지막 작업이고, 배치, 색상, 스타일 등을 끝까지 작업한다. 웹 페이지의 디자인과 공급과 관련한 프로세스를 명확히 파악할 필요가 있다.
매우 기본적인 것처럼 보이지만 실상은 매우 흥미롭다. 사실, 엄청난 양의 “성분(stuff)”들이 있다. 이것은 주로 4 단계와 5 단계 사이에 발생하고 바로, 이 부분을 이 글에서 중점적으로 다룰 것이다. 대부분의 프로그래머들은 사용자의 브라우저가 이것을 디스플레이 하도록 요청 받으면 대부분의 프로그래머들은 자신들의 마크업에 어떤 일이 발생하는지 정확히 고려하지 않기 때문이다.
이 모든 질문들에 대한 답은 Document Object Model이다. 이제 본격적으로 DOM을 논해보자. 프로그래머의 작업이 끝날 때 웹 브라우저가 시작된다. 다시 말해서, HTML 파일을 웹 서버 상의 디렉토리에 얹어 놓으면 보통 이것을 "완료된 것 "으로 정리해 놓고 절대로 다시는 생각하지 않는다! 깨끗하고, 구성이 잘된 페이지를 작성할 때도 이것은 너무 멋진 목표이다. 여러분의 마크업이 브라우저를 통해 다양한 버전의 CSS와 JavaScript로 디스플레이 하기를 원하는데 이것도 잘못은 아니다. 문제는 이러한 접근 방식이 브라우저에서 실제로 무슨 일이 일어나는지에 대해 프로그래머가 알 수 있는 범위를 제한한다는 점이다. 더욱이 클라이언트 측 JavaScript를 사용하여 웹 페이지를 동적으로 업데이트, 변경, 재구현 할 수 있는 기능 까지 제한한다. 이러한 한계를 제거하고 더 나아가 웹 사이트에서 더 나은 인터랙션과 생산성을 도모할 수 있다. 웹 프로그래머로서 여러분은 텍스트 에디터와 IDE를 시작하고 HTML, CSS, 심지어 JavaScript를 입력하기 시작한다. 태그, 셀렉터, 애트리뷰트를 사이트가 올바르게 보일 수 있도록 하는 작은 태스크라고 생각하기 쉽다. 하지만 그러한 관점을 좀더 확장 할 필요가 있다. 여러분이 콘텐트를 구성하고 있다는 것을 깨달아야 한다. 걱정하지 말라. 마크업의 가치에 대해 일장 연설을 늘어놓으려는 것은 아니다. 웹 페이지의 진정한 가치를 깨닫는 방법 내지는 형이상학적인 무엇인가를 설명하려는 것도 아니다. 여러분이 이해해야 할 것은 웹 개발 시 여러분의 역할이 정확히 무엇인가를 이해해야 한다. 페이지를 보이게 해야 하는 시점에 와서 여러분은 제안만 할 수 있을 뿐이다. 여러분이 CSS 스타일시트를 제공하면 사용자는 여러분의 스타일을 무시할 수 있다. 폰트 사이즈를 제공하면 사용자의 브라우저는 그러한 사이즈를 변경할 수 있고 모니터에 맞게 스케일링 할 수 있다. 폰트와 컬러도 사용자의 모니터에 맞게 선택할 수 있다. 페이지를 스타일링 할 때 최선을 다하는 것도 중요하지만 이는 웹 페이지에 큰 영향을 주지 못한다. 여러분이 완벽히 제어하는 것은 웹 페이지의 구조이다. 여러분의 마크업은 변경할 수 없고 사용자는 이것을 망칠 수 없다. 브라우저는 웹 서버에서 이것을 가져와서 디스플레이 한다. (여러분의 구미 보다 사용자의 구미에 따라 스타일로) 하지만 이 페이지의 구성은-이 단어가 그 문단 내에 있든 다른 div에 있든-전적으로 여러분에 달려있다. 페이지를 실제로 변경할 때(이것은 대부분의 Ajax 애플리케이션들이 집중하는 것이다.) 이것은 여러분이 운영하는 페이지의 구조이다. 텍스트의 조각의 색상을 변경하는 것이 좋지만 텍스트나 전체 섹션을 기존 페이지에 추가하는 것이 훨씬 더 좋다. 사용자가 그 섹션을 어떻게 스타일링 하던지 간에 페이지 그 자체의 구성을 가지고 작업한다. 마크업이 구성에 관한 것이라는 것을 깨달으면 이것을 달리 볼 수 있다. 스타일과 작동(이벤트 핸들러와 JavaScript)가 fact 뒤에 이 구성에 적용된다는 것도 명확해 진다. 마크업은 적소에서 작동되거나 스타일링 되어야 한다. 따라서 HTML에 대한 외부 파일에 CSS를 갖는 것처럼 마크업의 구성도 스타일, 포맷팅, 작동과 분리된다. 엘리먼트의 스타일 또는 텍스트 조각을 JavaScript로부터 확실히 변화시킬 수 있고 마크업이 레이아웃 한 구성을 실제로 바꿀 수 있다는 것은 더 흥미 있는 사실이다. 마크업이 페이지에 구성 또는 프레임웍만 제공한다는 것을 마음에 새긴다면 본격적인 게임에 돌입해보자. 브라우저가 모든 텍스트 구성을 가지고, 이를 변경, 추가, 삭제 가능한 객체로 바꾸는 방법을 보자.
웹 브라우저를 논하기 전에 왜 플레인 텍스트가 HTML을 저장하기에 최상의 선택인지를 생각해 봐야 한다. (마크업에 대해 더 알아야 할 것들 참조) 찬반을 논하기 전에, 페이지가 보여질 때 마다 HTML이 네트워크를 통해 웹 브라우저로 보내진다는 것을 생각해 보라. (캐싱 같은 문제는 차후에 논하기로 한다.) 텍스트와 함께 전달하는 것 보다 효율적인 방법은 없다. 바이너리 객체, 그래픽으로 구현된 페이지, 재구성된 마크업 청크 등, 이 모든 것들은 플레인 텍스트 파일 보다 네트워크를 통해 전송할 때 더 어려운 것들이다. 브라우저를 이러한 방정식에 대입해 보자. 오늘날의 브라우저에서는 사용자가 텍스트의 크기길 변경하고, 이미지를 스케일링 하고 CSS나 JavaScript를 다운로드 할 수 있다. 이 모든 것은 페이지의 온갖 종류의 그래픽 표현을 브라우저로 보내는 전조가 된다. 대신 브라우저는 미가공 HTML을 필요로 한다. 왜냐하면 이것은 태스크를 핸들하기 위해 서버를 믿기 보다 어떤 프로세싱이든 브라우저에 있는 페이지에 적용할 수 있기 때문이다. 같은 맥락에서, CSS와 JavaScript를 분리하고, 이들을 HTML 마크업에서 분리할 때에는 분리하기 쉬운 포맷이 필요하다. HTML 4.01, XHTML 1.0/ 1.1 같은 새로운 표준들이 콘텐트(페이지의 데이터)를 표현과 스타일(보통 CSS에 의해 적용됨)에서 분리하겠다는 약속을 기억하는가? 프로그래머들이 CSS에서 HTML을 분리하려면 브라우저를 실행하여 페이지에서 몇몇 구현들을 가져오고 그러한 표준의 많은 장점들을 없앤다. 브라우저에서 이렇게 다른 부분들을 계속 분리시키면 브라우저는 서버에서 HTML을 가져올 때 최상의 유연성을 보인다. 지금까지 여러분이 읽은 모든 것은 웹 개발 프로세스에서의 여러분의 역할에 대한 리뷰에 불과하다. 하지만 웹 브라우저가 무엇을 수행하는지를 논해야 하는 시점에서 유능한 많은 웹 디자이너와 개발자들은 보이지 않는 곳에서 실제로 어떤 일이 발생하는지 종종 깨닫지 못한다. 이 섹션에서는 바로 그 부분을 설명하도록 하겠다. 걱정하지 말라. 코드도 함께 등장할 것이다. 잠시 코딩하고 싶은 조바심을 접어두라. 웹 브라우저가 정확히 어떤 일을 수행하는지를 이해하는 것이 정확한 코딩 작업의 필수이기 때문이다. 텍스트 마크업이 디자이너나 페이지 생성자에게 엄청난 이득을 주듯이 브라우저에는 비교적 큰 단점을 갖고 있다. 특히 브라우저는 텍스트 마크업을 사용자에게 시각적으로 직접 나타내기가 매우 힘들다. (마크업에 대해 더 알아야 할 것들 참조) 다음과 같은 브라우저 태스크를 생각해 보라.
복잡함은 이러한 태스크들을 코딩 하는데 있는 것이 아니다. 이러한 일들을 하기는 정말 쉽다. 복잡함은 브라우저가 실제로 요청된 액션을 수행하는 데서 온다. 마크업이 텍스트로 저장되면
이 같은 매우 어려운 질문들 때문에 몇몇 사람들이 오늘날 브라우저를 코딩을 한다. 확실히, 플레인 텍스트는 브라우저를 위해 HTML을 저장하는 최상의 방법은 아니다. 텍스트가 페이지의 마크업을 가져오는 좋은 솔루션이었지만 말이다. 이 외에도 JavaScript가 페이지의 구조를 변경하는 기능은 트릭이 조금 있다. 브라우저가 수정된 구조를 디스크에 재작성 해야 하는가? 문서의 현재 어떤 단계에 있는지를 어떻게 파악할 수 있는가? 확실히 텍스트는 답이 못 된다. 수정하기도 어렵고, 스타일과 작동을 추가하기에는 불편하고, 궁극적으로 오늘날 웹 페이지의 동적인 특징과 거리가 멀다. 이 문제에 대한 답, 오늘날의 웹 브라우저에 맞는 답은 트리 구조를 사용하여 HTML을 나타내는 것이다. 텍스트 마크업으로 구현된 단순하고 지루한 HTML 페이지 대신 Listing 1을 보자. Listing 1. 텍스트 마크업의 간단한 HTML 페이지
그림 1. 이 브라우저는 이것을 트리 구조로 변환한다. 그림 1. Listing 1의 트리 뷰 이 글을 위해 단순함을 유지했다. DOM과 XML 전문가는 공백이 문서에 있는 텍스트가 구현되고 웹 브라우저의 트리 구조에서 깨지는 방법에 영향을 줄 수 있다는 것을 알 것이다. 공백의 효과에 대해 알고 있다면 정말 대단하다. 그렇지 않다면 공부하면 된다. 걱정 말라. 이것이 문제가 될 때 필요한 것이 무엇인지를 깨닫게 될 것이다. 실제 트리 백그라운드 외에 여기에서 알아야 할 첫 번째 것은 트리에 있는 모든 것이 가장 바깥쪽에서 시작되고 HTML의 엘리먼트( 루트에서부터 마크업의 다양한 조각들 간 관계를 보여주는 라인의 흐름을 따라가 보라. 트리 메타포를 이해하기 위해서 기본적인 용어들을 익혔으니 엘리먼트 이름과 텍스트가 들어있는 작은 직사각형에 집중해 보자.(그림 1) 각 직사각형들은 객체이다. 여기에서 브라우저는 텍스트와 관련된 문제들을 해결한다. 객체를 사용하여 HTML 문서의 조각들을 나타냄으로서 구성을 변경하고, 스타일을 적용하며, JavaScript를 문서에 액세스 시키기가 매우 쉬워진다. 모든 가능한 유형의 마크업은 고유의 객체 유형을 갖는다. 예를 들어, HTML에 있는 엘리먼트는 따라서 웹 브라우저는 객체 모델을 사용하여 문서를 표현하고—정적 텍스트를 다룰 필요가 없음—객체 유형에 따라 즉각 구분할 수 있다. HTML 문서는 파싱되고 그림 1의 객체들로 바뀐다. 그런 다음 대괄호 같은 이스케이프 시퀀스로 바뀐다. 이는 브라우저의 작업을 훨씬 쉽게 만든다. 적어도 인풋 HTML을 파싱한 후에도 말이다. 어떤 것이 엘리먼트이고 어떤 것이 애트리뷰트인지 파악하고 객체 유형을 어떻게 다룰지를 결정하는 작동은 간단하다. 객체들을 사용함으로서 웹 브라우저는 그러한 객체들의 속성들을 변경할 수 있다. 예를 들어, 각 엘리먼트 객체는 하나의 부모와 자식 리스트를 갖고 있다. 새로운 자식 엘리먼트나 텍스트를 추가하는 것은 새로운 자식을 엘리먼트의 자식 리스트에 추가하는 문제에 지나지 않는다. 이러한 객체들은 또한
다시 말해서, 웹 브라우저는 이와 같이 객체 속성들을 사용하여 트리의 모양과 구조를 쉽게 변경한다. 이것을 복잡한 것과 비교해 보라. 속성과 구조가 변할 때 마다 브라우저는 정적 파일을 재작성 하고, 재 파싱 하고 이를 스크린에 다시 디스플레이 해야 한다. 이 모든 것이 객체로도 가능해진다. 이 시점에서 HTML 문서에 대해 알아보고 이를 트리로 그려보자. 평범한 요청은 아닌 것 같지만 이들을 다룰 수 있으려면 이러한 트리 구조에 익숙해져야 한다. 보통의 요청은 아닌 것 같지만 이 트리 구조에 익숙해져야 한다. 이들을 조작할 수 있으려면 말이다. 이 프로세스에서 몇 가지 이상한 점들을 발견하게 된다. 다음과 같은 상황을 생각해 보자.
일단 이러한 유형의 문제에 익숙해지면 다음 섹션을 이해하기가 더 쉬울 것이다. 내가 언급했던 것을 직접 해본다면 마크업의 트리 뷰에 잠재적 문제 몇 가지들을 발견할 것이다. (직접 하지 않을 것이라면 내 말을 믿어라.) 사실, Listing 1과 그림 1에서 여러 가지를 발견할 것이다.
더욱이 순서도 문제가 된다. 정확한 마크업이지만 여러분의 HTML에서 제공된 순서와 다르다면 사용자가 웹 브라우저에 어떻게 대응할지를 상상할 수 있겠는가? 문서를 구성했던 방식이 아닐 때에도 제목과 헤딩 사이에 끼게 될 것이다. 브라우저는 엘리먼트와 텍스트의 순서를 보존해야 한다. 이 경우,
이 순서를 섞는다면 텍스트의 잘못된 부분에 강조를 적용한 것이다. 이 모든 것을 바로잡으려면 이 개념을 이해하는 것은 매우 중요하다. "really" 텍스트가 나머지 이를 유념하면서 Listing 2와 3의 HTML을 다이어그램으로 그리면서 텍스트에 정확한 부모를 유지하도록 한다. 정확한 부모로 유지시킨다. Listing 2. 약간의 트릭이 들어간 엘리먼트 중첩이 있는 마크업
Listing 3. 보다 트릭이 심한 엘리먼트의 중첩
이러한 관행에 대한 해답은 이 글 끝부분의 GIF 파일인 tricky-solution.gif (그림 2)와 trickier-solution.gif (그림 3)에서 찾을 수 있다. 스스로 알아내기 전에 몰래 보지 않기를 바란다. 엄격한 규칙이 트리를 구성하는데 어떻게 적용되는지를 이해하면 도움이 될 것이다. HTML과 트리 구조를 마스터 한다면 정말로 도움이 될 것이다. 애트리뷰트를 어떻게 다루어야 하는지를 파악할 때 문제가 생긴 적이 있는가? 앞서 언급했지만 애트리뷰트는 고유의 객체 유형을 갖고 있지만 애트리뷰트는 엘리먼트의 자식이 아니다. 중첩 엘리먼트와 텍스트는 같은 레벨의 애트리뷰트가 아니고 Listing 2와 3에 대한 답에는 애트리뷰트가 나타나지 않는다는 것을 알 수 있다. 사실 애트리뷰트는 브라우저가 사용하는 객체 모델에 저장되지만 이들은 특별한 경우이다. 각 엘리먼트는 여기에 사용되는 애트리뷰트 리스트를 갖고 있고 자식 객체의 리스트에서 분리된다. 따라서 엘리먼트용 애트리뷰트가 유일한 이름을 갖고 있어야 한다는 것을 기억하라. 다시 말해서, 하나의 엘리먼트가 두 개의 "id" 또는 두 개의 "class"애트리뷰트를 가질 수 없다. 보존하고 액세스 할 리스트를 매우 쉽게 만든다. 다음 글에서 보겠지만 애트리뷰트의 독자성은 리스트를 자식 객체들의 리스트와 구별시킨다. 더 진행하기에 앞서 브라우저가 마크업을 트리 구현으로 변환하는 방법, 브라우저가 엉성한 폼의 마크업을 어떻게 다루는지를 볼 필요가 있다. 구성이 잘되었다(Well-formed)는 용어는 XML에서 광범위하게 사용되고 두 가지 기본적인 의미가 있다.
이 두 가지 규칙들을 자세히 연구해 보자. 두 규칙 모두 문서의 간단한 구성을 늘릴 뿐만 아니라 모호함을 제거한다. Bolding이 먼저 적용되고 그 다음에 italics를 적용해야 하는가? 아니면 그 반대인가? 순서와 다의성이 큰 문제인 것처럼 보이지만 CSS에서는 이 규칙들이 다른 규칙들을 무시할 수 있도록 한다. 따라서 잘 구성되지 않은 문서를 브라우저가 받는 경우 할 수 있는 최선을 다한다. 결과 트리 구조는 가장 좋은 경우는 원래 페이지 작성자가 의도했던 것과 비슷한 것이고 최악의 경우 완전히 다른 것이다. 브라우저에 페이지를 로딩하고 기대했던 것과 완전히 다른 일이 발생한다면 구조에 대해 다시 생각해 봐야 한다. 물론 픽스는 간단하다. 문서가 잘 구성되었는지를 확인하는 것이다. 표준화된 HTML을 작성하는 방법을 모르겠다면 참고자료를 참조하라. 지금 까지, 브라우저가 웹 페이지를 객체 구현으로 변환하는 것에 대해 배웠다. 아마도 여러분은 객체 구현이 DOM 트리라고 생각해왔을 것이다. DOM은 문서 객체 모델(Document Object Model)을 의미하고 World Wide Web Consortium (W3C)에서 사용할 수 있는 스팩이다.(참고자료) DOM은 브라우저가 마크업을 나타낼 수 있도록 하는 객체의 유형과 속성들을 정의한다. (다음 글에서는 JavaScript와 Ajax 코드에서 DOM을 사용하는 방법을 설명하겠다.) 무엇보다도 객체 모델에 액세스 해야 한다. 이것은 매우 쉽다. 웹 페이지에서 실행되는 JavaScript 코드 조각에 있는 빌트인
물론 이 코드는 그 자체로는 쓸모가 없지만 모든 웹 브라우저가 document 객체를 JavaScript 코드에 사용할 수 있도록 하고 객체는 완벽한 마크업 트리를 나타낸다.(그림 1) 확실히, JavaScript로 프로그래밍을 했다면 DOM 코드를 사용하는 방법도 알 것이다. 이 Ajax 시리즈를 충실히 이행했다면 여러분도 DOM 코드를 사용한 것이다. 예를 들어, 여러분이 배웠던 용어를 정비하기 위해 DOM 트리는 객체의 트리지만 보다 구체적으로는 노드 객체들의 트리이다. Ajax 애플리케이션 또는 JavaScript에서 그러한 노드들과 작업하여 엘리먼트와 이것의 콘텐트를 지우고 특정 텍스트 조각을 강조하고 새로운 이미지 엘리먼트를 추가하는 등 특별한 효과를 만들 수 있다. 이 모든 것은 클라이언트 측(웹 브라우저에서 실행되는 코드)에서 발생하기 때문에 이러한 효과는 서버와 통신 없이 즉시 발생한다. 결국 보다 반응성 있는 애플리케이션이 될 것이다. 대부분의 프로그래밍 언어에서 각 노드 유형에 맞는 실제 객체 이름들을 배우고 속성들을 배우고 유형과 캐스팅을 파악해야 한다. 하지만 이중 어떤 것도 JavaScript에서는 필요하지 않다. 변수를 만들어서 여기에 원하는 객체를 할당한다.
변수를 만들고 여기에 정확한 유형을 핸들하는 유형과 JavaScript는 없다. 결과적으로 JavaScript에서 DOM을 사용하기가 매우 쉬워진다. (다음 글에서는 XML과 관련한 DOM에 초점을 맞춰 설명하겠다.) 지금 여기에서 설명한 것이 DOM의 전부는 아니다. 사실 이 글은 DOM의 개요서에 지나지 않는다. 오늘 설명한 것 이상의 것이 DOM에는 있다. 다음 글에서는 JavaScript에서 DOM을 사용하여 웹 페이지를 만들고 HTML을 수정하고 사용자 인터랙션을 높이는 방법을 설명하겠다. DOM을 주제로 다시 한면 설명하겠다. Ajax 애플리케이션의 중요한 부분인 DOM에 익숙해지기 바란다. 바로 지금 DOM을 더 깊이 연구할 수 있다. DOM 트리로 옮기는 방법, 엘리먼트와 텍스트의 값을 얻는 방법, 노드 리스트를 통해 반복하는 방법 등을 자세히 설명하겠다. 무엇보다도 트리 구조에 대해 생각해 보고 HTML을 통해서 웹 브라우저가 HTML을 마크업의 트리 뷰로 어떻게 전환하는지에 대해 생각해 보고 다음 글에 임하기 바란다. 또한, DOM 트리의 구성을 생각해 보고 이 글에 설명된 특별한 경우를 생각해 보라. 애트리뷰트, 그 안에 엘리먼트와 혼합된 텍스트, 텍스트 콘텐트를 갖고 있지 않은 엘리먼트( 이러한 개념을 확실히 이해하고 JavaScript와 DOM의 신택스를 배운다면 도움이 될 것이다. 여기 Listing 2와 2에 대한 답을 제시하겠다. 샘플 코드도 포함되어 있다. 그림 2. Listing 2에 대한 답 Figure 3. The answer to Listing 3 교육
제품 및 기술 얻기 토론
|
'그거 > Java' 카테고리의 다른 글
Ajax 마스터하기, Part 6: DOM-기반 웹 애플리케이션 구현하기 (0) | 2007.01.29 |
---|---|
Ajax 마스터하기, Part 5: DOM 다루기 (0) | 2007.01.29 |
Ajax 마스터하기, Part 3: Ajax의 고급 요청 및 응답 (0) | 2007.01.29 |
Ajax 마스터하기, Part 2: JavaScript와 Ajax를 이용한 비동기식 요청 (0) | 2007.01.29 |
Ajax 마스터하기, Part 1: Ajax 소개 (한글) (0) | 2007.01.29 |