문서 스크립팅

2014. 11. 26. 17:05 나홀로스터디/JS 완벽가이드

15장 문서 스크립팅

이 포스팅은 "자바스크립트 완벽 가이드(인사이트, 송인철,이동기,이유원,황인석 옮김)"에서 발췌 요약한 것입니다.
 
15.1 동적인 문서 내용
15.2 Document의 프로퍼티
15.3 레거시 DOM : Document 객체의 집합
15.4 W3C DOM의 개요
15.5 문서순회
15.6 문서 내 엘리먼트 찾기
15.7 문서 수정하기
15.8 문서에 새로운 내용 추가하기


클라이언트 측 자바스크립트는 정적인 HTML문서를 대화식 웹 애플리케이션으로 만들기 위해 존재한다.
모든 웹 브라우저 창(또는 프레임)은 HTML 문서를 화면에 나타내고 Window 객체는 이 창을 표현하기 위한 객체이며 여기에는 Document 객체를 참조하는 document 프로퍼티가 있다.
Document Object Model(DOM)은 문서를 구성하는 객체에 어떻게 접근할 것인가를 정의하는 API다.


15.1 동적인 문서 내용
Document 객체에 있는 write() 메서드는 두가지 방법으로 사용할 수 있는데 첫 번째 방법은 현재 파싱되고 있는 문서에 HTML을 출력하기 위해 스크립트 안에서 이 메서드를 사용하는 것이다. 하지만 현재 문서에 HTML을 출력하기 위해 write()를 사용하는 것은 이 문서가 파싱되는 동안에만 가능하기 때문에 document.write()를 <script> 태그에 있는 최상위 레벨의 코드 안에서만 호출할 수 있다.
다른 창이나 프레임에 완전히 새로운 문서를 생성하기 위해 (Document 객체의 open()과 close() 메서드와 함께) 이 write() 메서드를 사용할 수 있다. 일반적으로 문서는 이벤트 처리기 안에서 절대 자신에 대해 write()를 호출해서는 안된다.

write() 메서드는 두 개 이상의 전달인자를 받을 수 있다.
Document 객체는 writeIn() 메서드를 지원한다. 이 메서드는 전달인자를 출력한 후 끝에 줄바꿈 문자를 붙여 넣는다는 점만 제외하면 write() 메서드와 동일하다.

 


15.2 Document의 프로퍼티

bgColor
문서의 배경색이다. 이 프로퍼티는 <body> 태그의 bgcolor(권장하지 않는 프로퍼티) 어트리뷰트다.


cookie
자바스크립트 프로그램이 HTTP 쿠키를 읽거나 쓸 수 있게 해주는 특수한 프로퍼티다.


domain
이 프로퍼티는 같은 인터넷 도메인 안에 있는 서로 신용하는 웹 서버의 웹 페이지들끼리 서로 정보를 주고받을 때 동일 출처 정책을 완화할 수 있게 해준다.


lastModified
문서가 수정된 날자를 저장한 문자열이다.


location
URL 프로퍼티와 동의어인데 지금은 제외되었다.


referrer
웹 브라우저를 현재 페이지로 연결시켜준 링크가 있는 문서의 URL이다.


title
현재 문서의 <title>과 </title> 태그 사이에 있는 텍스트다.


URL
문서가 위치한 주소가 어디인지 나타내는 문자열이다. 이 프로퍼티의 값은 서버 리다이렉트(redirect)가 발생한 경우를 제외하면 Window 객체의 location.href 프로퍼티와 같다.

 

 

15.3 레거시 DOM : Document 객체의 집합
배열값을 가지는 Document 객체의 집합 프로퍼티들은 레거시(legacy) DOM의 심장부다.


anchors[]
문서 내의 앵커들을 표현하는 Anchor 객체의 배열이다. (앵커란 문서 내에서 이름이 붙여진 위치, <a>태그에 href 대신 name 어트리뷰트를 적어서 생성한다) Anchor 객체의 name 프로퍼티 값은 태그에 있는 name 어트리뷰트의 값이다.


applets[]
문서 내의 자바 애플릿을 표현하는 Applet 객체의 배열이다.


forms[]
문서 내의 <form> 원소를 표현하는 Form 객체의 배열이다. 각 Form 객체에는 폼 내에 포함되어 있는 폼 원소들을 표현하는 집합 프로퍼티인 elements[ ]가  있다. Form 객체는 폼이 제출되기 전에 onsubmit 이벤트 처리기를 호출한다.


imgaes[]
문서 내의 <img> 원소를 표현하는 Image 객체의 배열이다. Image 객체의 src 프로퍼티는 읽고 쓸수 있는 프로퍼티이고, 어떤 URL을 이 프로퍼티에 할당하면 브라우저가 새로운 이미지를 읽어 들여 화면에 표시한다.


links[]
문서 내의 하이퍼텍스트 링크를 표현하는 Link 객체의 배열이다. 하이퍼텍스트 링크는 <a> 태그와, 경우에 따라서는 클라이언트 측 이미지 맵에 있는 <area> 태그를 통해 생성된다. Link 객체의 href 프로퍼티는 <a> 태그의 href 어트리뷰트에 해당하고 이 어트리뷰트의 값은 링크의 URL이다. 또한 Link 객체는 protocol, hostname, pathname 같은 프로퍼티를 통해 URL의 다양한 컴포넌트를 사용할 수 있게 한다.

이 프로퍼티들의 원소 각각은 문서의 소스코드에 나타나는 순서대로 저장된다.
레거시 DOM의 집합에 속하는객체들을 사용해 스크립팅 할 수는 있찌만 이를 사용하여 문서의 구조를 변경할 수는 없다는 사실을 이해하는 것이 중요하다.

 


15.3.1 Document 객체 이름 짓기
번호로 인덱싱되는 Document 객체의 집합에서 생기는 문제점은 위치 기반의 인덱스가 잘못 사용되기 쉽다는 것이다. 이를 해결하기 위한 안정적인 방법은 문서 내의 중요한 원소에 이름을 부여한 후 이런 원소에 접근할 때는 각 원소에 부여된 이름을 사용하는 것이다.

<form name="f1"><input type="button" value="Push Me"></form>
document.forms[0]; // 문서 내의 위치를 통해 폼을 참조 document.forms.f1;  // 프로퍼티로 이름을 통해 폼을 참조 document.forms["f1"]  // 배열 인덱스로 이름을 통해 폼을 참조

<form>이나 <img>, <applet>(<a> 태그에는 해당되지 않는다)의 name 어트리뷰트를 설정하는 것은 각각에 해당하는 Form이나 Image, Applet 객체(Link나 Anchor 객체에는 해당되지 않는다)를 Document 객체의 프로퍼티로서 접근할 수 있게 해준다.

document.f1 

만약 한 문서에서 두 원소의 name 어트리뷰트 값이 같으면 프로퍼티는 두 원소에 대한 참조를 가지는 배열이 된다. 일반적으로 HTML 폼에서 서로 관련된 라디오 버튼의 이름이나 체크박스의 이름은 같다. 이렇게 하면 이 이름은 라디오 버튼과 체크 박스들을 가지는 Form 객체의 프로퍼티가 되고, 이 프로퍼티의 값은 다양한 라디오 버튼이나 체크 박스 객체들에 대한 참조를 가진 배열이 된다.

 

15.3.2 Document 객체에 대한 이벤트 처리기
사용자와 정보를 주고받기 위해서는 HTML문서나 이 문서 내의 원소들이 사용자 이벤트에 반응할 수 있어야 한다.
document.links와 같이 객체 집합을 통해 접근되는 Document 객체에는 HTML 태그의 어트리뷰트에 해당하는 프로퍼티가 있다.
HTML에서 이벤트 처리기는 이벤트 처리기 어트리뷰트에 자바스크립트 코드 문자열을 할당하는 작업을 통해 정의된다. 하지만 자바스크립트에서는 이벤트 처리기 프로퍼티에 함수를 할당하는 작업을 통해 이벤트 처리기를 정의한다.

 


15.4 W3C DOM의 개요

15.4.1 문서를 트리로 표현
HTML 문서의 중첩된 태그는 DOM에서 트리로 표현되는 계층적 구조이다. HTML 문서의 트리 표현은 <body>와 <p> 같은 HTML 태그와 원소를 나타내는 노드, 텍스트의 문자열을 표현하는 노드를 가진다.


15.4.2 노드
Node 인터페이스에는 트리를 순회하거나 조작하기 위한 프로퍼티와 메서드가 정의되어 있다. Node 객체의 childeNodes 프로퍼티는 자기 자식들의 목록을 반환하고 firstChild와 lastChild, nextSibling, previousSibling, parentNode는 노드로 구성된 트리를 순회하기 위한 수단을 제공한다.  appendChild()와 removeChild(), replaceChilde(), insertBefore() 같은 메서드는 여러분이 문서 트리에 노드를 삽입하거나 제거할 수 있게 해준다.


15.4.2.1 노드의 타입
문서를 나타내는 트리의 여러 노드는 각 노드의 특정한 하위 인터페이스를 통해 표현된다. 모든 Node 객체에는 노드가 어떤 타입에 속하는지를 나타내는 nodeType 프로퍼티가 정의되어 있다. DOM 트리의 최상위에 있는 노드는 Document 객체다. 이 객체의 documentElement 프로퍼티는 문서의 최상위 원소를 표현하는 Element 객체를 참조하는데 HTML 문서에서는 문서 내에 명시적이거나 비명시적으로 적혀있는 <html> 태그가 이에 해당한다.
DOM 트리에는 Document 원소가 단 한개만 존재한다. 트리 내의 대다수 노드들은 <html> 이나 <i> 같은 태그를 표현하는 Element 객체와 텍스트의 문자열을 표현하는 Text 객체다. 문서를 분석하는 파서가 문서에 있는 주석을 유지하고 있다면 이 주석은 Comment 객체를 통해 DOM 트리상에 표현된다.


15.4.2.2 어트리뷰트
Element 인터페이스에 있는 getAttribute()와 setAttribute(), removeAttribute() 메서드를 사용하여 원소의 어트리뷰트 값을 읽거나 설정, 삭제할수 있다. HTML 태그의 표준 어트리뷰트는 각 태그를 표현하는 Element 객체의 프로퍼티로도 존재한다.
어트리뷰트를 사용하여 작업을 하는 다른 방법은 어트리뷰트와 그 값을 표현하는 Attr 객체를 반환해주는 getAttributeNode() 라는 메서드를 사용하는 것이다. (이 방법을 사용하는 이유는 Attr 인터페이스에 어트리뷰트의 값이 문서상에 리터럴로 기술되어 있는지 혹은 기본값인지 판단할 수 있게 해주는 specified라는 프로퍼티가 정의되어 있기 때문이다.)
하지만 Attr 객체는 원소의 childNodes[] 배열에는 나타나지 않고 Element나 Text 노드처럼 문서 트리 상에 직접 나타나는 것도 아니라는 사실을 유의하라.

15.4.3 DOM HTML API
DOM 표준은 XML이나 HTML과 함께 사용하려는 목적으로 만들어졌다.
HTMLDocument 인터페이스에는 W3C 표준화이전에 만들어진 브라우저들이 지원했던 다양한 프로퍼티와 메서드가 정의되어 있고 id와 style, title, lang, dir, className 프로퍼티가 정의되어 있다. ('class'는 자바스크립트의 예약어이기 때문에 HTML의 class 어트리뷰트가 자바스크립트에서는 className이 되었다.) HTML 태그는 여섯가지 어트리뷰트들 이외에 다른 어트리뷰트는 추가할 수 없다.

DOM 표준은 스크립트 작성자의 편의를 도모하기 위해 HTML 어트리뷰트에 대한 프로퍼티를 정의하고 있다는 점을 유념하라. 어트리뷰트 값을 얻어내거나 설정하는 일반적인 방법은 Element 객체의  getAttribute()setAtrribute() 메서드를 사용하는 것이고 HTML 표준이 아닌 어트리뷰트를 사용하여 작업할 때는 이 메서드를 사용해야 한다.


15.4.3.1 HTML 작명법
HTML은 대소문자를 구분하지 않지만 자바스크립트는 대소문자를 구분한다. HTML에 특화된 인터페이스의 프로퍼티 이름은 소문자로 시작하고 프로퍼티 이름이 여러 개의 단어로 이루어졌다면 두 번째 단어부터는 대문자로 시작한다.


 

15.4.4 DOM 레벨과 기능
DOM 표준에는 두 가지 버전(혹은 레벨)이 있다.
DOM 레벨 1은 1998년 10월에  표준화 되었고  여기엔 Node와 Element, Attr, Document 같은 코어 DOM 인터페이스들이 정의되어 있고 HTML에 특화된 다양한 인터페이스들도 정의되어 있다.  DOM 레벨 2는 2000년 11월에 표준화 되었고 이 DOM은 코어 인터페이스에 몇가지를 수정하는것 외에도 문서 이벤트와 CSS 스타일시트에 대해서 작업할수 있는 추가적인 도구도 제공한다.  그러나 마이크로소프트는 DOM event 모듈을 구현하지 않으며 레거시 DOM, W3C DOM, IE DOM은 서로 다른 방법으로 이벤트를 처리한다.




15.4.5 DOM 인증
현재 브라우저의 수가 너무 많아졌고 표준 지원 범위도 급격하게 빨리 변화하고 있어 이 책에서 어떤 브라우저가 어떤 DOM 기능을 지원하는지 명확한 정보를 알려주기 어렵다. 따라서 웹 브라우저가 DOM을 얼마나 잘 구현하고 있는지 판단하려면 지원 여부를 확인하는 것이 필요하다.


15.4.5.1 인터넷 익스플로러에서 DOM 인증
IE는 Node 인터페이스가 정의하는 node 타입의 상수를 지원하지 않는다. 문서 내의 각 노드에는 자신이 어떤 타입인가를 나타내는 nodeType 이라는 프로퍼티가 있다는 사실을 기억하라.


 

15.4.6 언어에 독립적인 DOM 인터페이스
이 책은 DOM API의 자바스크립트 구현에 대해 설명하지만 구현의 객체 프로퍼티는 일반적으로 다른 언어에 있는 get/set 메서드의 쌍에 매핑된다. DOM API의 자바스크립트 구현에서 또 다른 중요한 점은 특정 DOM 객체가 자바스크립트 배열처럼 작동한다는 것이다.
DOM 객체에 namedItem() 메서드가 있다면 메서드에 문자열을 전달하는 것은 객체의 배열 인덱스로 문자열을 사용하는 것과 같다. 다음 코드는 모두 폼 원소에 접근하는 동일한 방법이다.

var f = document.forms.namedItem["myform"];
var g = document.forms["myform"];
var h = document.forms.myform; 

NodeList의 원소에 접근하기 위해 배열 표현법을 사용할 수는 있지만, NodeList가 단지 배열과 유사한 객체이며 실제 Array는 아니라는 점을 반드시 기억해야 한다. DOM의 구현은 어떤 클래스를 정의하든지 상관이 없지만 다양한 DOM 인터페이스의 메서드와 프로퍼티는 반드시 정의해야 한다.



 

15.5 문서순회
DOM은 HTML문서를 Node 객체의 트리로  표현한다. 트리구조를 사용하여 가장 많이 이루어지는 작업은 트리의 각 노드를 차례대로 검사하면서 트리를 순회하는 것이다.


 

15.6 문서 내 엘리먼트 찾기
Document 객체는 모든 DOM 트리의 최상위 노드이지만 트리에 있는 HTML 엘리먼트는 표현하지 않는다. document.documentElement 프로퍼티는 문서의 최상위 엘리먼트인 <html> 태그를 참조하고 document.body 프로퍼티는 <body> 태그를 참조하는데 이 태그는 자신의 부모인 <html> 태그보다 유용하게 사용된다.
특정 타입의 HTML 엘리먼트 목록을 얻기 위해 getElementsByTagName()을 사용할수 있는데 html 태그는 대소문자를 구분하지 않기 때문에 전달되는 문자열도 대소문자가 구분되지 않는다는 점을 명심하라.
getElementByTagName()은 엘리먼트들의 배열을 반환하는 데 반해 getElementById() 메서드는 단지 id 어트리뷰트에 매칭되는 단일 엘리먼트만 반환한다.
HTML 문서의 HTMLDocument 객체에는 getElementByName() 메서드도 정의되어 있는데 이것은 엘리먼트 name 어트리뷰트를 조사하며 name 어트리뷰트는 문서 내에서 유일한 값을 가지지 않을 수도 있기 때문에 엘리먼트들의 배열을 반환한다.
클래스나 태그 이름을 통해 엘리먼트를 선택할 수 있게 해주는 getElements() 메서드에는 주어진 HTML 엘리먼트가 주어진 클래스의 멤버인지 검사하는 isMember() 메서드가 포함되어 있다.


 

15.7 문서 수정하기
코어 DOM API의 진정한 힘은 자바스크립트를 사용하여 문서를 동적으로 수정할 수 있다는데 있다.  Text 노드 내에 있는 텍스트에는 appendData(), inserData(), deletetData(), replaceData() 메서드를 사용하여 텍스트를 덧붙이거나 새 텍스트를 추가할 수 있고 기존 텍스트를 삭제하거나 교체할 수 있다.


15.7.1 어트리뷰트 수정하기
element.setAttribute() 메서드는 텍스트 교체와 부모 바꾸기, 노드 재배열하기를 통해 문서를 수정하는것 외에도 문서의 엘리먼트에 있는 어트리뷰트를 설정하여 문서를 다양하게 변형할 수 있다.


15.7.2 DocumentFragment를 사용하여 작업하기
DocumentFragment는 문서 내에서 실제로 나타나지는 않고 노드의 집합을 저장하고 저장된 노드들의 임시 저장소 역할을 담당한다.  또한 DocumentFragment에 저장된 노드들은 DocumentFragment를 통해 마치 단일 객체인 것처럼 조작할 수 있다. DocumentFragment가 문서에 삽입되면 (Node 객체의 appendChild()나 insertBefore(), replaceChild() 메서드 중 하나를 사용하여) 그때부터는 DocumentFragment는 자신의 노드들로 대체된다.


 

15.8 문서에 새로운 내용 추가하기
Document.createElemnet()Document.createTextNode() 메서드는 새로운 Element와 Text 노드를 생성하고 이렇게 생성한 노드는 Node.appendChild(), Node.insertBefoe(), Node.replaceChild() 메서드로 문서에 추가한다.


15.8.1 노드를 생성할 때 편리하게 사용할 수 있는 메서드
테이블을 생성하기 위해 Element를 생성하고 이것의 어트리뷰트를 설정한 후 Text 노드를 생성하고 이 Text 노드를 Element에 추가하고 이것을 부모 Element에 추가하는 과정은 복잡했다. 이것은  make()라는 함수를 통해 할수 있는데 이 이름으로 Element를 생성하고 이 객체에 대한 어트리뷰트를 설정한 후 자식들을 추가한다.


15.8.2 innerHTML 프로퍼티
HTMLElement 노드의 innerHTML을 W3C에서 공식적으로 DOM의 일부분으로 승인한 적은 없지만 현대의 모든 브라우저가 지원하는 중요하고도 강력한 프로퍼티다. HTML 엘리먼트에 대해 이 프로퍼티 값을 요청했을 때 얻는것은 그 엘리먼트 자식을 표현하는 HTML 텍스트 문자열이다. 대체로 HTML 문서를 HTML 텍스트 문자열로 기술하는 것이 createElement()와 appendChild()의 호출을 나열하는 것보다 훨씬 간편하고 간단하다.
웹 브라우저는 HTML 파싱 능력이 뛰어나다. += 연산자를 사용하여 아주 적은 양의 텍스트를 innerHTML 프로퍼티에 추가하는 것은 직렬화 과정과 파싱 과정을 모두 필요로 하기 때문에 그다지 효율적이지 않다.


 

15.9 예: 동적으로 생성되는 목차
문서 내에서 사용자가 선택한 텍스트가 무엇인지 알아내는 기능은 표준화가 진행되진 않았지만 현재 모든 브라우저에서 기능을 제공하고 있다. Window와 Document 객체의 getSelection() 메서드가 <input>이나 <textarea> 내에 있다면 선택된 텍스트를 반환하지 않고 브라우저별 호환성 문제가 있다.



 

'나홀로스터디 > JS 완벽가이드' 카테고리의 다른 글

쿠키와 클라이언트 측 지속성  (0) 2014.12.23
CSS와 DHTML  (0) 2014.12.15
웹 브라우저와 자바스크립트  (0) 2014.11.18
함수  (0) 2014.10.27
객체와 배열  (0) 2014.10.20
Copyright © HuckleberryM All Rights Reserved | JB All In One Designed by CMSFactory.NET