Please note, this is a STATIC archive of website developer.mozilla.org from November 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Migrate apps from Internet Explorer to Mozilla

소개

넷스케이프가 Mozilla 브라우저를 시작할때 부터 Mozilla는 W3C 표준을 지원하기로 결정되었다. 그 결과 Mozilla는 Netscape Navigator 4.x와 Microsoft Internet Explorer의 구형 코드와는 완전한 하위호환성을 가지지 못하게 되었다. 예를 들어, 뒤에서 언급하겠지만 Mozilla는 <layer>를 지원하지 않는다. W3C 표준의 개념 이전에 만들어진 IE 4와 같은 브라우저들은 많은 쿼크들을 물려받았다. 본 글에서는 IE와 기타 구형 브라우저들과의 강력한 HTML 하위 호환성을 제공하는 Mozilla의 쿼크 모드에 관해 알아볼 것이다.

또한 XMLHttpRequest와 리치 텍스트 편집과 같은, 당시에는 W3C에 이에 상응하는 것이 존재하지 않았기 때문에 Mozilla가 지원하는 비표준 기술에 대해서도 언급하겠다. 그것은 다음을 포함한다:

일반적인 크로스 브라우저 코딩 팁

웹표준이 존재하긴 하지만, 서로다른 브라우저는 서로 다르게 작동한다. (사실, 같은 브라우저라도 플랫폼에 따라 다르게 작동한다.) IE와 같은 많은 브라우저들이 W3C 이전의 API들도 지원하며 W3C 적용 API들에 대한 확장된 지원을 추가하지 않았다.

Mozilla와 IE 사이의 차이점을 논하기 전에, 추후 새로운 브라우저를 지원할 수 있도록 확장성있는 웹 어플리케이션을 만들 수 있는 기본적인 방법을 다루도록 하겠다.

서로 다른 브라우저들이 가끔 같은 기능에 대해 서로 다른 API를 사용하기 때문에, 브라우저들간에 구별을 위해 코드 전반적으로 여러개의 if() else() 블록을 사용하는 것을 종종 볼 수 있다. 다음 코드는 IE를 위해 고안된 코드 블록을 보여준다.

. . . 

var elm; 

if (ns4) 
  elm = document.layers["myID"]; 
else if (ie4) 
  elm = document.all["myID"]

위의 코드는 확장성이 없기 때문에 새로운 브라우저를 지원하고 싶으면 웹 어플리케이션 전체에 있는 이러한 블록들을 수정해야만 한다.

새로운 브라우저 추가를 위해 코딩을 다시하는 것을 막을 수 있는 가장 쉬운방법은 기능성을 추상화하는 것이다. 여러개의 if() else() 블록 보다는 공통적인 기능을 취하여 그 기능만으로 추상화시킴으로써 효율성을 증가시킬 수 있다. 이것은 코드의 가독성을 높일 뿐만 아니라, 새로운 클라이언트에 대한 지원을 추가하는 것을 단순화 시킨다.

var elm = getElmById("myID"); 

function getElmById(aID){ 
  var element = null; 

  if (isMozilla || isIE5) 
    element = document.getElementById(aID);
  else if (isNetscape4) 
    element = document.layers[aID];
  else if (isIE4) 
    element = document.all[aID];

  return element; 
} 

위의 코드는 아직 브라우저 스니핑 혹은 사용자가 어느 브라우저를 사용하고 있는가의 문제를 안고 있다. 브라우저 스니핑은 보통 다음과 같은 useragent를 통하여 행해 진다:

Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031016 

useragent로 브라우저를 스니핑하는 것이 사용중인 브라우저에 대한 세부 정보를 제공하기는 하지만, useragents를 다루는 코드는 종종 새로운 브라우저 버전이 출시될때 실수를 일으킬 수 있으며 그래서 코드를 바꿔야 할 수도 있다.

브라우저의 타입에 상관없다면 (웹 어플리케이션 접근에 대해 지원되지 않는 브라우저는 이미 차단했다고 가정할때), 브라우저가 가진 기능이나 오브젝트 특성 지원으로부터 스니핑하는 것이 훨씬 더 좋고 더욱 신뢰성이 있다. 이것은 보통 자바스크립트에서 필요한 기능이 존재하는지를 검사해보는 것으로 행해진다. 예를들면 다음보다는:

if (isMozilla || isIE5) 

이것을 사용하는 것이다:

if (document.getElementById) 

이는 Opera와 Safari같이 W3C 표준 메소드를 지원하는 다른 브라우저들이 아무런 수정을 하지 않고도 작동할 수 있게 한다.

그러나 useragent 스니핑은 브라우저가 웹 어플리케이션의 버전 요구사항을 만족시키는지를 검사할때나 버그와 관련한 작업과 같이 정확도가 중요할때 의미가 있다.

자바스크립트는 인라인 조건문도 허용하는데 이것은 코드 가독성을 증가시킨다:

var foo = (condition) ? conditionIsTrue : conditionIsFalse; 

예를 들면, 엘리먼트를 얻기 위해 다음을 사용한다:

 
function getElement(aID){ 
  return (document.getElementById) ? document.getElementById(aID)
                                   : document.all[aID];
} 

혹은 || 연산자를 사용한 다른 방법도 있다.

function getElement(aID){ 
  return (document.getElementById(aID)) || document.all[aID]);
}

Mozilla와 IE 간의 차이점

우선 Mozilla와 IE간의 HTML이 동작하는 방법에서의 차이점 부터 알아보겠다.

툴팁

구형 브라우저들은 링크상에 툴팁을 보여주거나 툴팁의 내용으로 alt 속성 값을 사용함으로써 툴팁을 도입했다. 최근의 W3C HTML 스펙은 title 속성을 만들었는데 이것은 링크의 세부 설명을 포함할 수 있다. 오늘 날의 브라우저들은 툴팁을 보여주기 위해 title 속성을 사용할 것이다. 그리고 Mozilla는 title 속성으로 툴팁을 보여주는 것만을 지원하며 alt 속성은 지원하지 않는다.

엔티티

HTML 마크업은 몇몇 엔티티를 포함할 수 있는데, 이 엔티티는 W3C 웹 표준 본문에 정의되어 있다. 엔티티는 숫자형이나 캐릭터 레퍼런스로 참조될 수 있다. 예를 들면, 공백 문자 #160은 &#160; 또는 동등한 캐릭터 레퍼런스인 &nbsp;로 참조될 수 있다.

IE와 같은 몇몇 오래된 브라우저들은 보통의 텍스트 컨텐츠의 끝에서 ;(세미콜론)을 생략하여 엔티티를 사용하는 것을 가능하게 하는 쿼크들을 가지고 있었다.

&nbsp Foo 
&nbsp&nbsp Foo 

IE는 비록 W3C 스펙에 어긋나기는 하지만 위의 &nbsp를 공백으로 렌더링한다. 브라우저는 만약 바로 직후에 다른 문자가 오면 &nbsp를 파싱하지 않는다. 예를들면,

&nbsp12345 

이 코드는 Mozilla에서는 동작하지 않는다. 왜냐하면 W3C 웹표준에 어긋나기 때문이다. 브라우저간의 불일치를 피하려면 항상 정확한 형식(&nbsp;)을 사용하라.

DOM 차이

Document Object Model (DOM)은 문서 엘리먼트를 포함하고 있는 트리구조이다. W3C가 표준화한 자바스크립트 API로 이것을 조작할 수 있다. 그러나, W3C 표준화 이전에 넷스케이프 4와 IE 4는 유사하게 API를 구현했다. Mozilla는 W3C 웹표준으로 이룰 수 없는 경우에만 구식 API를 구현했다.

엘리먼트 접근

크로스 브라우저 접근법을 사용해서 엘리먼트 레퍼런스를 탐색하기 위해서는 document.getElementById(aID)를 사용하는데, 이것은 IE 5.0+, Mozilla기반 브라우저, 그리고 다른 W3C 적용 브라우저들에서 작동하며 DOM Level 1 스펙의 일부이다.

Mozilla는 document.elementName이라던지 엘리먼트의 name을 통해서 접근하는 방법을 지원하지 않는 반면에 IE는 이를 지원한다. (global namespace polluting이라고도 부른다.) Mozilla는 넷스케이프 4의 document.layers 메소드나 IE의 document.all 메소드도 지원하지 않는다. document.getElementById가 하나의 엘리먼트를 찾아내는 방법인 반면에 document.layersdocument.all를 사용하면 모든 <div> 엘리먼트들과 같이 특정 태그명의 모든 문서 엘리먼트들의 리스트를 얻을 수 있다.

W3C DOM Level 1 메소드는 getElementsByTagName()을 통해 같은 태그명을 가진 모든 엘리먼트들에 대한 레퍼런스를 얻을 수 있다. 이 메소드는 자바스크립트에서 배열로 반환되며, document 엘리먼트에 호출되거나, 다른 노드들에 그 하위 구조만을 탐색하게 호출할 수 있다. DOM 트리에서 모든 엘리먼트들에 대한 배열을 얻으려면 getElementsByTagName("*")를 사용한다.

표 1에서 보는 바와 같이, DOM Level 1 메소드는 엘리먼트를 특정 위치로 옮기거나 (메뉴, 에니메이션 등을) 보이게 혹은 안보이게 하는데 공통적으로 쓰인다. 넷스케이프 4는 Mozilla가 지원하지 않는 <layer>태그를 아무곳에나 위치시킬 수 있는 HTML 엘리먼트로사용했다. Mozilla에서는 <div> 태그를 사용하여 어떠한 엘리먼트라도 위치시킬 수 있는데, 이것은 IE도 잘 사용되며 HTML 스펙에 나와있는 것이다.

표 1. Methods used to access elements
Method Description
document.getElementById( aId ) Returns a reference to the element with the specified ID.
document.getElementsByTagName( aTagName ) Returns an array of elements with the specified name in the document.

DOM 탐색

Mozilla는 자바스크립트를 통하여 DOM 트리를 탐색하는 W3C DOM API를 지원한다(표 2 참조). 이 API는 문서 내에 있는 각 노드들에 대해 존재하고 아무 방향으로나 탐색하는 것이 가능하다. IE도 이 API들을 잘 지원하지만 IE는 children 속성처럼 DOM 트리를 탐색할 수 있는 구식 API들도 역시 지원한다.

표 2. Methods used to traverse the DOM
Property/Method Description
childNodes Returns an array of all child nodes of the element.
firstChild Returns the first child node of the element.
getAttribute( aAttributeName ) Returns the value for the specified attribute.
hasAttribute( aAttributeName ) Returns a boolean stating if the current node has an attribute defined with the specified name.
hasChildNodes() Returns a boolean stating whether the current node has any child nodes.
lastChild Returns the last child node of the element.
nextSibling Returns the node immediately following the current one.
nodeName Returns the name of the current node as a string.
nodeType Returns the type of the current node.
Value Description
1 Element Node
2 Attribute Node
3 Text Node
4 CDATA Section Node
5 Entity Reference Node
6 Entity Node
7 Processing Instruction Node
8 Comment Node
9 Document Node
10 Document Type Node
11 Document Fragment Node
12 Notation Node
nodeValue Returns the value of the current node. For nodes that contain text, such as text and comment nodes, it will return their string value. For attribute nodes, the attribute value is returned. For all other nodes, null is returned.
ownerDocument Returns the document object containing the current node.
parentNode Returns the parent node of the current node.
previousSibling Returns the node immediately preceding the current one.
removeAttribute( aName ) Removes the specified attribute from the current node.
setAttribute( aName, aValue ) Sets the value of the specified attribute with the specified value.

IE는 비표준 쿼크를 가지는데 이들 API의 많은 수가 뉴라인 같이 생성된 공백 텍스트 노드를 무시한다. Mozilla는 이를 무시하지 않는다. 그래서 가끔씩 이들 노드를 구별해 줄 필요가 있다. 모든 노드들은 노드 타입을 지정하는 nodeType 속성을 가지고 있다. 예를 들어, 엘리먼트 노드는 타입 1이고 텍스트 노드는 타입 3이며 주석 노드는 타입 8이다. 엘리먼트 노드만을 처리하기 위한 가장 좋은 방법은 모든 자식 노드들을 순환문을 돌려서 nodeType이 1인 노드들만 처리하는 것이다.

HTML: 
  <div id="foo">
    <span>Test</span>
  </div>

JavaScript: 
  var myDiv = document.getElementById("foo"); 
  var myChildren = myDiv.childNodes; 
  for (var i = 0; i < myChildren.length; i++) { 
    if (myChildren[i].nodeType == 1){ 
      // element node
    };
  };

컨텐츠의 생성과 조작

Mozilla는 document.write, document.open, document.close와 같이 DOM에 동적으로 컨텐츠를 추가하는 구형 메소드를 지원한다. Mozilla는 IE의 innerHTML 메소드도 지원하는데 이것은 거의 모든 노드에서 호출 가능하다. 그러나, outerHTML(엘리먼트 주변에 마크업을 추가하며 표준은 없다.)와 innerText(노드의 텍스트 값을 지정하며 Mozilla에서는 textContent를 사용하여 조작가능)는 지원하지 않는다.

IE는 비표준이며 Mozilla에서는 지원하지 않는 몇몇 컨텐츠 조작 메소드를 가지고 있는데 여기에는 값을 추출해 내거나 텍스트를 삽입하고 getAdjacentElement, insertAdjacentHTML와 같은 노드 주변에 엘리먼트를 삽입하는 것들이 포함된다. 표3은 W3C와 Mozilla가 어떻게 컨텐츠를 조작하는지를 보여주며, 모두 어떠한 DOM 노드에서라도 사용할 수 있는 메소드들이다.

표 3. Methods Mozilla uses to manipulate content
Method Description
appendChild( aNode ) Creates a new child node. Returns a reference to the new child node.
cloneNode( aDeep ) Makes a copy of the node it is called on and returns the copy. If aDeep is true, it copies over the node's entire subtree.
createElement( aTagName ) Creates and returns a new and parentless DOM node of the type specified by aTagName.
createTextNode( aTextValue ) Creates and returns a new and parentless DOM textnode with the data value specified by aTextValue.
insertBefore( aNewNode, aChildNode ) Inserts aNewNode before aChildNode, which must be a child of the current node.
removeChild( aChildNode ) Removes aChildNode and returns a reference to it.
replaceChild( aNewNode, aChildNode ) Replaces aChildNode with aNewNode and returns a reference to the removed node.

도큐먼트 프래그먼트

실행 성능상의 이유로 현재 존재하고 있는 문서의 DOM에서 작업하기 보다 메모리 상에서 도큐먼트를 생성할 수 있다. DOM Level 1 Core는 도큐먼트 프래그먼트를 도입했는데 이것은 보통의 도큐먼트 인터페이스의 부분집합을 가지는 경량의 도큐먼트이다. 예를 들어, getElementById는 존재하지 않지만 appendChild는 존재한다. 또한 현재 존재하고 있는 도큐먼트에 쉽게 도큐먼트 프래그먼트를 추가할 수 있다.

Mozilla 는 document.createDocumentFragment()를 통하여 빈 도큐먼트 프래그먼트를 생성할 수 있다.

그러나 IE에서의 도큐먼트 프래그먼트 구현은 W3C 웹표준을 따르지 않으며 단순히 보통의 도큐먼트를 리턴한다.

자바스크립트 차이

Mozilla와 IE간의 대부분의 차이점은 보통 자바스크립트에 대한 것이다. 그러나 이러한 문제들은 DOM hook과 같이 브라우저가 자바스크립트에 대해 드러내는 API들에서는 보통 거짓이다. 두 브라우저간 코어 자바스크립트의 차이점은 거의 없다. 문제는 타이밍 관련된 이슈에서 종종 생긴다.

자바스크립트 날짜 차이

단하나의 Date 차이점은 getYear 메소드이다. ECMAScript 스펙(자바스크립트가 따르는 명세)에 따르면 이 메소드는 2004년에 new Date().getYear()를 실행시키면 "104"를 리턴한다. ECMAScript 스펙에 따르면 getYear는 해당년도에서 1900을 뺀 수를 리턴한다. 이것은 본래 1998년에 대해 "98"을 리턴하는 의미였다. getYear는 ECMAScript 버전3에서 deprecated되었고 getFullYear()로 교체되었다. IE는 Netscape 4(포함) 이전 버전과 비슷하게 1900-1999년인 경우 연도에서 1900을 뺀 값을 다른 연도는 그대로를 반환(즉, 1999년인 경우 getYear()는 99를 2000년인 경우 2000을 반환한다)하는 못쓰게 된 비헤비어 getYear()를 쓴다.

자바스크립트 실행 차이

서로다른 브라우저는 자바스크립트를 다르게 실행한다. 예를 들어, 다음 코드는 script 코드 실행 시점에 DOM 내에 div 노드가 이미 존재하고 있음을 가정한다.

...
<div id="foo">Loading...</div>

<script> 
  document.getElementById("foo").innerHTML = "Done."; 
</script> 

그러나, 이것은 보장할 수 없다. 모든 엘리먼트가 존재함을 보장하기 위해서는 <body>태그에 onload 이벤트 핸들러를 사용해야 한다.

<body onload="doFinish();"> 

<div id="foo">Loading...</div> 

<script> 
  function doFinish() { 
    var element = document.getElementById("foo");
    element.innerHTML = "Done."; 
  }
</script> 
... 

이러한 타이밍 관련 문제에는 하드웨어도 역시 관련된다. 느린 시스템에서는 빠른 시스템에서 감춰지는 버그들이 드러날 수 있다. 확실한 예 중의 하나는 새 윈도우를 여는 window.open이다.

<script> 
  function doOpenWindow(){ 
    var myWindow = window.open("about:blank"); 
    myWindow.location.href = "https://www.ibm.com"; 
  }
</script> 

위의 코드가 갖고 있는 문제는 window.open이 비동기라는 것이다. 이것은 윈도우가 로딩을 마칠때 까지 자바스크립트 실행을 차단해 놓지 않는다. 그러므로, 새 윈도우가 뜨기도 전에 window.open 라인의 다음 라인이 실행될 수가 있다. 이것은 새 창에서 onload 핸들러를 가지게 하고 (window.opener를 사용하여) 새 창을 연 윈도우로 콜백 실행을 하게 하여 해결할 수 있다.

자바스크립트가 생성하는 HTML의 차이

자바스크립트는 document.write를 사용하여 문자열에서 HTML을 생성해낼 수 있다. 여기에서의 주요 문제는 HTML 문서 내부에 포함된 (즉, <script> 태그 내부의) 자바 스크립트가 <script>태그를 포함한 HTML을 생성하는 경우이다. 만약 문서가 strict 렌더링 모드라면 문자열 내부의 </script> 태그를 바깥쪽의 <script>에 대한 닫는 태그로서 파싱할 것이다. 다음 코드는 이것을 가장 잘 설명한다.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
 "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
... 
<script> 
  document.write("<script type='text/javascript'>alert('Hello');</script>") 
</script> 

페이지가 strict 모드이므로, Mozilla의 파서는 첫번째 <script>를 보고 이에 대한 닫는 태그를 찾을때까지, 즉 첫번째 </script>를 찾을때까지 파싱한다. 이것은 파서가 strict 모드일때 자바스크립트 (혹은 다른 언어)에 관해 모르기 때문이다. 쿼크 모드에서 파서는 파싱시 (느려짐) 자바스크립트에 대해 알고 있다. IE는 항상 쿼크 모드이다 그래서 IE는 진정한 XHTML을 지원하지 않는다. 이것을 Mozilla의 strict 모드에서 작동하게 하려면 문자열을 두부분으로 분리한다:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
 "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
... 
<script> 
  document.write("<script type='text\/javascript'>alert('Hello');</" + "script>") 
</script> 

자바스크립트 디버깅

Mozilla는 IE를 위해 만들어진 어플리케이션들에서 발견되는 자바스크립트 관련 문제들을 디버깅할 수 있는 몇가지 방법을 제공한다. 첫번째 툴은 그림 1에서 보는 것처럼 내장된 자바스크립트 콘솔이다. 여기에는 에러와 경고가 표시된다. Mozilla에서 도구 -> Web Development -> JavaScript Console를 실행하거나 파이어폭스 (Mozilla에서 나온 단독 브라우저 제품)에서는 도구 -> JavaScript Console를 실행한다.

그림 1. JavaScript 콘솔

Javascript 콘솔

자바스크립트 콘솔은 에러나 경고, 혹은 메시지에 대한 전체 기록 목록을 보여줄 수 있다. 그림 1의 에러 메시지는 aol.com의 95번째 라인이 is_ns70이라는 정의되지 않은 변수를 접근하려한다는 것을 알려준다. 링크를 클릭하면 Mozilla의 내부 소스보기 창이 열리고 해당 라인이 하이라이트되어 있을 것이다.

콘솔에서는 자바스크립트를 실행할 수도 있다. 입력한 자바스크립트 문법을 실행하려면 그림 2처럼 입력창에 1+1을 치고 Evaluate를 누르면 된다.

그림 2. JavaScript console evaluating

JavaScript Console evaluating

Mozilla의 자바스크립트 엔진은 디버깅에 대한 내장된 지원을 하므로 자바스크립트 개발자들에게 강력한 툴을 제공할 수 있다. 그림 3에 있는 Venkman은 Mozilla에 통합된 강력한 크로스 플랫폼 자바스크립트 디버거이다. 이것은 보통 Mozilla 릴리즈에 포함된다. 도구 -> Web Development -> JavaScript Debugger로 가면 찾을 수 있다. 파이어 폭스에서는 이 디버거가 포함되어 있지 않다. 대신에 Venkman Project Page에서 다운로드 받아 설치할 수 있다. Venkman Development Page에 있는 개발 관련 페이지에서는 튜토리얼도 찾을 수 있다.

그림 3. Mozilla의 JavaScript 디버거

Mozilla의 JavaScript 디버거

자바스크립트 디버거는 Mozilla 브라우저 창에서 실행중인 자바스크립트를 디버깅할 수 있다. 이것은 breakpoint관리, call stack inspection 혹은 variable/object inspection과 같은 표준 디버깅 기능들을 지원한다. 모든 기능들은 사용자 인터페이스를 통하거나 디버거의 대화 콘솔을 통하여 접근할 수 있다. 콘솔을 사용하면 현재 디버깅하는 자바스크립트와 같은 스코프에서 임시적인 자바스크립트를 실행시킬 수 있다.

CSS 차이

Mozilla 기반의 제품군은 IE를 비롯한 다른 브라우저에 비해 CSS1, CSS2.1 및 CSS3 일부를 포함한 CSS를 강력하게 지원한다.

아래에 설명하는 대부분의 문제들에 대해, Mozilla는 자바스크립트 콘솔에 에러나 경고 메시지를 표시할 것이다. 만약 CSS 관련 문제에 직면하게 되면 자바스크립트 콘솔을 확인하라.

Mimetypes (CSS 파일이 적용되지 않을시)

가장 일반적인 CSS관련 문제는 참조된 CSS 파일 내부에 있는 CSS 정의가 적용되지 않는 것이다. 이것은 보통 서버가 CSS 파일에 대한 틀린 마임타입을 보낼 때 생기는 문제이다. CSS 스펙을 보면 CSS 파일은 반드시 text/css 마임타입으로 취급되게 되어 있다. Mozilla는 웹페이지가 strict 표준 모드일때 이러한 마임타입을 찾을 것이며 이러한 마임타입 일때만 CSS파일을 로드한다. IE는 어떠한 마임타입이라도 상관없이 항상 CSS파일을 로드한다. 웹페이지는 strict doctype으로 시작될때 strict 표준모드로 여겨진다. 이 문제를 해결하기 위해서는 서버가 올바른 마임타입을 보내게 하거나 doctype을 제거한다. doctype에 관한 자세한 내용은 다음 섹션에서 살펴보도록 하겠다.

CSS와 단위

많은 웹어플리케이션들이 CSS에서 단위를 사용하지 않는데, 특히 자바스크립트로 CSS를 설정할때가 그렇다. Mozilla는 페이지가 strict 모드가 아닌한 이를 참고 넘어간다. IE는 진정한 XHTML을 지원하지 않기 때문에 단위가 표시되지 않아도 상관하지 않는다. 만약 페이지가 strict 표준모드인데 단위가 쓰이지 않았다면 Mozilla는 해당 스타일을 무시한다:

<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
  "https://www.w3.org/TR/html4/strict.dtd"> 
<html> 
  <head> 
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <title>CSS and units example</title> 
  </head> 
  <body> 
    // works in strict mode 
    <div style="width: 40px; border: 1px solid black;">
      Text
    </div>

    // will fail in strict mode 
    <div style="width: 40; border: 1px solid black;">
      Text
    </div>
  </body> 
</html> 

위 예제는 strict dcotype을 가지므로 본 페이지는 strict 표준 모드로 렌더링된다. 첫번째 div는 단위가 쓰였기 때문에 40px의 너비를 갖는다. 그러나 두번째 div는 너비값이 지정 안되어 기본값인 100%의 너비를 갖게된다. 이것은 자바스크립트를 통해 설정되었을때도 마찬가지다.

JavaScript 와 CSS

Mozilla는 CSS표준을 지원하므로, 자바스크립트로 CSS를 지정할때 CSS DOM 표준도 역시 지원한다. 임의의 엘리먼트의 style 멤버를 통해 엘리먼트의 CSS 룰에 접근하거나 삭제, 변경할 수 있다:

<div id="myDiv" style="border: 1px solid black;">
  Text
</div>

<script>
  var myElm = document.getElementById("myDiv"); 
  myElm.style.width = "40px"; 
</script>

이러한 방식으로 모든 CSS 속성에 접근할 수 있다. 만약 웹페이지가 strict 모드라면 단위를 지정해야 하며, 그렇지 않을 시 Mozilla는 해당 명령을 무시한다. Mozilla와 IE에서 .style.width를 통해 값을 얻으면 반환된 값은 단위를 포함하며, 이는 문자열이 반환됨을 의미한다. 이 문자열은 parseFloat("40px")을 통해 숫자로 변환할 수 있다.

CSS 오버플로우 차이

CSS는 오버플로우에 대한 표기를 추가했는데 이것은 오버플로우를 어떻게 처리할 것인가를 정의할 수 있게 해준다. 예를들어 그 높이보다 더 긴 컨텐츠를 갖는 div와 같은 경우이다. CSS 표준에서는 이경우에 오버플로우 속성이 지정되지 않았다면 div 컨텐츠는 오버플로우 된다고 정의한다. 그러나, IE는 이를 지키지 않고 컨텐츠를 담을 수 있을 만큼 div의 높이를 확장한다. 아래는 이 차이를 보여주는 예제다.

<div style="height: 100px; border: 1px solid black;">
  <div style="height: 150px; border: 1px solid red; margin: 10px;">
    a
  </div>
</div>

그림 4에서 볼 수 있듯이, Mozilla는 W3C 표준이 정의한대로 행동한다. W3C 표준에서 이경우에, 안쪽 div는 그 부모보다 높이가 크므로 bottom에서 오버플로우된다고 되어 있다. 만약 IE 쪽의 행동이 더 마음에 든다면, 단순히 바깥쪽 엘리먼트의 높이를 지정하지 않으면 된다.

그림 4. DIV overflow

DIV Overflow

hover 차이

IE에서의 비표준 CSS hover 작동이 소수의 웹사이트에서 일어난다. Mozilla에서는 보통 텍스트 위에 hover되었을때 그 텍스트 스타일을 변경하므로써 그 자체를 명확히하지만, IE에서는 그렇지 않다. 이것은 IE에서는 a:hover에 대한 CSS 셀렉터가 <a name="">...</a>가 아닌 <a href="">...</a>에 매치되기 때문이다. 다음의 텍스트는 그 영역을 앵커 태그로 감쌌기 때문에 변화가 일어날 것이다:

CSS:
  a:hover {color: green;}

HTML:
  <a href="foo.com">This text should turn green when you hover over it.</a>

  <a name="anchor-name">
    This text should change color when hovered over, but doesn't
    in Internet Explorer.
  </a>

Mozilla는 CSS 스펙을 정확하게 따르며 이 예제에서 색깔은 녹색으로 바뀔것이다. Mozilla가 IE처럼 행동하게 하여 hover 오버시 텍스트 색이 바뀌지 않게 하는 법은 두가지 방법이 있다:

  • 첫번째, CSS 룰을 a:link:hover {color: green;}로 바꾸면 엘리먼트가 링크일때만(href 속성을 가질때만) 색깔을 바꾼다.
  • 아니면, 텍스트 앞에서 열린 <a />태그를 닫는다. -- 이렇게 해도 앵커는 계속 작동할 것이다.

쿼크 vs. 표준 모드

IE 4와 같은 오래된 구식 브라우저에서는 특정 상황하에서 일명 쿼크라 불리는 모드로 렌더링 된다. Mozilla는 표준 적용을 지향하는 브라우저인 반면에, 이러한 쿼크 모드로 만들어진 오래된 웹페이지를 지원하는 세가지 모드를 가진다. 페이지의 컨텐츠와 전송이 Mozilla가 어느 모드를 사용할 것인지를 결정한다. Mozilla는 보기 -> 페이지 정보 (혹은 Ctrl+I)에서 렌더링 모드를 볼 수 있다. 파이어 폭스는 도구 -> 페이지 정보에서 렌더링 모드를 표시한다. 페이지가 어느 모드로 될 것인지는 doctype에 따라 결정된다.

Doctypes (간략한 문서 타입 선언)은 다음과 같은 형식이다:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">

파란 부분이 퍼블릭 식별자이고 녹색 부분이 시스템 식별자인데, URI로 되어 있다.

표준 모드

표준 모드는 가장 엄격한 렌더링 모드이다. 이것은 W3C의 HTML 스펙과 CSS 스펙으로 페이지를 렌더링 하며 어떠한 쿼크도 지원하지 않는다. Mozilla는 다음 조건에 대해 표준 모드를 사용한다:

  • 페이지가 text/xml 마임타입이나 다른 XML 혹은 XHTML 마임타입으로 보내졌을때
  • IBM doctype을 제외한 모든 "DOCTYPE HTML SYSTEM" doctype에 대해 (예를 들면, <!DOCTYPE HTML SYSTEM "https://www.w3.org/TR/REC-html40/strict.dtd">)
  • 알려지지 않은 doctype이나 DTD가 없는 doctype의 경우

반표준 모드

Mozilla는 한가지 이유때문에 반표준 모드를 도입했다: CSS 2 스펙의 한부분이 테이블 셀에 있는 작은 이미지들의 정확한 레이아웃을 기반한 디자인을 깬다는 것이다. 사용자에게 하나의 이미지로 보여지지 않고 각각의 작은 이미지 사이에 틈이 생긴다. 그림 5에서 볼 수 있듯이 예전 IBM 사이트에서 그 예를 찾을 수 있다.

그림 5. 이미지 간격

이미지 간격

반표준 모드는 이미지 갭 문제를 제외하고는 표준 모드와 거의 일치하는데, 이 문제는 표준 적용 페이지에서 종종 발생하며 페이지를 부정확하게 보여지게 만든다.

Mozilla는 다음의 경우에 반표준 모드를 사용한다:

  • 모든 "loose" doctype (예를 들면, <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">, <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">)
  • IBM doctype (<!DOCTYPE html SYSTEM "https://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd">)

image gap issue에서 더 많은 정보를 얻을 수 있다.

쿼크 모드

현재 웹은 브라우저에서 버그에 의해서만 작동하는 마크업들 뿐만 아닌, 유효하지 않은 HTML 마크업들로 가득 차 있다. 예전의 넷스케이프 브라우저는 넷스케이프가 시장의 선두주자였을때도 버그를 가지고 있었다. IE가 나왔을때 그것은 그시절의 컨텐츠들을 작동시키기 위해 그러한 버그들을 흉내내었다. 새로운 브라우저들이 시장으로 나옴에 따라 대부분의 원래 버그들(보통 쿼크라 부름)은 하위 버전 호환성을 위해 내버려 두었다. Mozilla는 쿼크 렌더링 모드에서 이러한것들의 많은 부분을 지원한다. 주의할 점은 이러한 쿼크들 때문에 페이지는 완전히 표준 적용모드일때보다 느리게 렌더링 될 것이라는 점이다. 대부분의 웹페이지는 이 모드에서 렌더링 된다.

Mozilla는 다음 조건에서 쿼크 모드를 사용한다:

  • doctype이 명시되지 않았을때
  • 시스템 식별자가 없는 doctype (예를 들면, <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">)

더 자세한 사항은 다음을 참고하라: Mozilla Quirks Mode Behavior, Mozilla's DOCTYPE sniffing.

이벤트 차이

Mozilla와 IE는 이벤트의 영역에서 거의 완전히 다르다. Mozilla의 이벤트 모델은 W3C와 넷스케이프 모델을 따른다. IE는 이벤트로부터 함수가 불려지면 이 함수는 window.event를 통해 event 오브젝트에 접근할 수 있다. Mozilla는 event 오브젝트를 이벤트 핸들러로 전달한다. Mozilla에서는 반드시 인수를 통해 불려진 함수로 오브젝트를 명시적으로 전달해야 한다. 크로스 브라우저 이벤트 핸들링 예제는 다음(코드 상에 event로 이름지어진 전역 변수를 정의할 수 없음을 유의)과 같다:

<div onclick="handleEvent(event);">Click me!</div>

<script>
  function handleEvent(aEvent) { 
    var myEvent = window.event ? window.event : aEvent;
  }
</script>

Mozilla와 IE에는 이벤트 오브젝트가 드러내는 속성과 함수도 종종 다르게 이름 지어졌는데 표4에 나와있는 것과 같다.

표 4. Event properties differences between Mozilla and Internet Explorer
Internet Explorer Name Mozilla Name Description
altKey altKey Boolean property that returns whether the alt key was pressed during the event.
cancelBubble stopPropagation() Used to stop the event from bubbling farther up the tree.
clientX clientX The X coordinate of the event, in relation to the element viewport.
clientY clientY The Y coordinate of the event, in relation to the element viewport.
ctrlKey ctrlKey Boolean property that returns whether the Ctrl key was pressed during the event.
fromElement relatedTarget For mouse events, this is the element from which the mouse moved away.
keyCode keyCode For keyboard events, this is a number representing the key that was pressed. It is 0 for mouse events. For keypress events (not keydown/keyup) of keys that produce output, the Mozilla equivalent is charCode, not keyCode.
returnValue preventDefault() Used to prevent the event's default action from occurring.
screenX screenX The X coordinate of the event, in relation to the screen.
screenY screenY The Y coordinate of the event, in relation to the screen.
shiftKey shiftKey Boolean property that returns whether the Shift key was pressed during the event.
srcElement target The element to which the event was originally dispatched.
toElement currentTarget For mouse events, this is the element to which the mouse moved.
type type Returns the name of the event.

이벤트 핸들러 등록

Mozilla는 자바스크립트를 통해 이벤트를 등록하는 두가지 방법을 지원한다. 첫번째는 모든 브라우저에서 지원되는 오브젝트에 직접적으로 이벤트 속성을 지정하는 방법이다. click 이벤트 핸들러를 지정하기 위해 함수 레퍼런스가 오브젝트의 onclick 속성에 전달된다:

<div id="myDiv">Click me!</div>

<script>
  function handleEvent(aEvent) {
    // if aEvent is null, means the Internet Explorer event model,
    // so get window.event.
    var myEvent = aEvent ? aEvent : window.event;
  }

  function onPageLoad(){
    document.getElementById("myDiv").onclick = handleEvent;
  } 
</script>

Mozilla는 DOM 노드에 리스너를 등록하는 W3C의 표준 방법을 전적으로 지원한다. addEventListener()removeEventListener() 메소드를 사용하면 동일한 이벤트 타입에 대해 여러 리스너를 지정할 수 있는 장점이 있다. 두 메소드는 세가지 파라미터를 필요로 한다 : 이벤트 타입, 함수 레퍼런스, 리스너가 캡쳐 구간에서 이벤트를 잡을 것인지에 대한 불린(boolean)값. 불린 값이 false로 지정되면, 버블링 이벤트만을 잡아낸다. W3C 이벤트는 capturing, at target, bubbling 세가지 단계을 가진다. 모든 이벤트 오브젝트는 단계를 숫자(0 인덱스)로 표시하는 eventPhase 속성을 가진다. 이벤트가 발생할 때 마다 이벤트는 DOM의 가장 바깥 엘리먼트, DOM 트리의 가장 상위 엘리먼트에서 출발한다. 그리고는 타겟을 향하여 가장 직접적인 경로를 사용하여 DOM을 타고 들어가는데 이것이 capturing 단계이다. 이벤트가 타겟에 도착하면 이벤트는 target 단계에 있는 것이다. 타겟에 도착한 후 이벤트는 다시 DOM 트리의 가장 바깥쪽으로 빠져 나가는데 이것이 bubbling 이다. IE의 이벤트 모델은 bubbling 단계만을 갖고 있기 때문에 IE의 동작과 같은 결과를 내려면 세번째 파라미터를 false로 지정해야 한다:

<div id="myDiv">Click me!</div> 

<script> 

  function handleEvent(aEvent) {
    // if aEvent is null, it is the Internet Explorer event model,
    // so get window.event.
    var myEvent = aEvent ? aEvent : window.event;
  }

  function onPageLoad() {
    var element = document.getElementById("myDiv");
    element.addEventListener("click", handleEvent, false);
  }
</script>

속성 지정보다 addEventListener()removeEventListener()를 사용하는 것의 장점 중 하나는 동일한 이벤트에 대해 각각 다른 함수를 호출하는 여러 이벤트 리스너를 가질 수 있다는 것이다. 그러므로 이벤트 리스너를 삭제하기 위해서는 추가할 때와 동일한 세개의 파라미터가 필요하다.

Mozilla는 IE의 <script> 태그를 이벤트 핸들러로 변환하는 메소드를 지원하지 않는데, 이것은 <script>를 forevent 속성으로 확장한다. (표 5.) Mozilla는 attachEventdetachEvent 메소드도 지원하지 않는다. 대신에 addEventListenerremoveEventListener 메소드를 써야 한다. IE는 W3C 이벤트 스펙을 지원하지 않는다.

표 5. Event method differences between Mozilla and Internet Explorer
Internet Explorer Method Mozilla Method Description
attachEvent(aEventType, aFunctionReference) addEventListener(aEventType, aFunctionReference, aUseCapture) Adds an event listener to a DOM element.
detachEvent(aEventType, aFunctionReference) removeEventListener(aEventType, aFunctionReference, aUseCapture) Removes an event listener to a DOM element.

리치 텍스트 편집

Mozilla가 W3C 표준을 가장 잘 적용한 브라우저라는 것을 자랑스러워하기는 하지만, W3C에 대응되는 표준이 없을 시 Mozilla는 innerHTML이나 rich text editing 같은 비표준 기능도 지원한다.

Mozilla 1.3은 IE의 designMode 기능 구현을 도입했는데 이것은 HTML 문서를 리치 텍스트 에디터 필드로 바꾼다. 일단 에디터로 바뀌고나면 명령들은 execCommand 명령을 통해 문서상에서 실행될 수 있다. Mozilla는 어떤 위젯이라도 편집가능하게 만드는 IE의 contentEditable 속성을 지원하지 않는다. 리치 텍스트 에디터를 추가하려면 iframe을 사용할 수 있다.

리치 텍스트 차이

Mozilla는 IFrameElmRef.contentDocument를 통해 iframe의 문서 오브젝트를 접근하는 W3C의 표준을 지원한다. 반면에 IE는 document.frames["IframeName"]를 통해 접근할 수 있고, 그 후 결과 document에 접근할 수 있다:

<script>
function getIFrameDocument(aID) {
  var rv = null; 

  // if contentDocument exists, W3C compliant (Mozilla)
  if (document.getElementById(aID).contentDocument){
    rv = document.getElementById(aID).contentDocument;
  } else {
    // IE
    rv = document.frames[aID].document;
  }
  return rv;
}
</script> 

Mozilla와 IE간의 또 다른 차이점은 리치 텍스트 에디터가 만들어내는 HTML이다. Mozilla는 기본적으로 생성된 마크업에 CSS를 사용하게 한다. 그러나 Mozilla는 useCSS execCommand를 사용하여 HTML과 CSS사이를 전환할 수 있게 한다. IE는 항상 HTML 마크업을 사용한다.

Mozilla (CSS): 
  <span style="color: blue;">Big Blue</span> 

Mozilla (HTML): 
  <font color="blue">Big Blue</font> 

Internet Explorer: 
  <FONT color="blue">Big Blue</FONT> 

아래는 Mozilla에서의 execCommand가 지원하는 명령 리스트이다:

표 6. Rich text editing commands
Command Name Description Argument
bold Toggles the selection's bold attribute. ---
createlink Generates an HTML link from the selected text. The URL to use for the link
delete Deletes the selection. ---
fontname Changes the font used in the selected text. The font name to use (Arial, for example)
fontsize Changes the font size used in the selected text. The font size to use
fontcolor Changes the font color used in the selected text. The color to use
indent Indents the block where the caret is. ---
inserthorizontalrule Inserts an <hr> element at the cursor's position. ---
insertimage Inserts an image at the cursor's position. URL of the image to use
insertorderedlist Inserts an ordered list (<ol>) element at the cursor's position. ---
insertunorderedlist Inserts an unordered list (<ul>) element at the cursor's position. ---
italic Toggles the selection's italicize attribute. ---
justifycenter Centers the content at the current line. ---
justifyleft Justifies the content at the current line to the left. ---
justifyright Justifies the content at the current line to the right. ---
outdent Outdents the block where the caret is. ---
redo Redoes the previous undo command. ---
removeformat Removes all formatting from the selection. ---
selectall Selects everything in the rich text editor. ---
strikethrough Toggles the strikethrough of the selected text. ---
subscript Converts the current selection into subscript. ---
superscript Converts the current selection into superscript. ---
underline Toggles the underline of the selected text. ---
undo Undoes the last executed command. ---
unlink Removes all link information from the selection. ---
useCSS Toggles the usage of CSS in the generated markup. Boolean value

더 자세한 사항은 다음을 참고하라: Rich-Text Editing in Mozilla.

XML 차이

Mozilla는 XSLT과 웹서비스와 같은 XML과 XML관련 기술에 대해 강력한 지원을 한다. Mozilla는 XMLHttpRequest과 같은 비표준 IE 확장도 지원한다.

XML을 다루는 법

표준 HTML 에서 처럼, Mozilla는 W3C XML DOM 스펙을 지원하며, 이것은 XML 문서의 거의 모든 면을 조작할 수 있게 한다. IE의 XML DOM과 Mozilla의 차이는 보통 IE의 비표준 동작에서 야기된다. 아마도 가장 일반적인 차이점은 공백 텍스트 노드를 어떻게 다루는가 이다. 종종 XML이 생성될 때 XML 노드 사이에 공백이 포함된다. IE는 XMLNode.childNodes[]를 사용할 때 이러한 공백 노드를 포함하지 않는다. 그러나 Mozilla에서는 이 노드들이 배열에 들어간다.

XML: 
  <?xml version="1.0"?> 
  <myXMLdoc xmlns:myns="https://myfoo.com"> 
    <myns:foo>bar</myns:foo> 
  </myXMLdoc>

JavaScript:
  var myXMLDoc = getXMLDocument().documentElement; 
  alert(myXMLDoc.childNodes.length); 

자바스크립트의 첫번째 라인이 XML 문서를 로드하고 documentElement를 탐색하여 루트 앨리먼트 (myXMLDoc)에 접근한다. 두번째 라인은 단순히 자식 노드의 수를 얼럿창에 띄운다. W3C 스펙에 따르면 공백과 줄바꿈은 서로 붙어 있을시 하나의 텍스트 노드로 합쳐진다. Mozilla의 경우에 myXMLdoc 노드는 세개의 자식을 가진다: 줄바꿈과 두개의 스페이스를 가진 텍스트 노드, myns:foo노드, 줄바꿈을 가진 또 하나의 텍스트 노드. 그러나, IE는 이것을 지키지 않고 위의 코드에 대해 1, 즉 myns:foo 노드만을 리턴한다. 그러므로 자식노드를 취하고 텍스트 노드를 버리기 위해, 이러한 노드들을 구별해 내야 한다.

앞서 언급했던 것처럼 모든 노드는 노드 타입을 가리키는 nodeType 속성을 가진다. 예를 들어, 엘리먼트 노드는 타입 1이고, 도큐먼트 노드는 타입 9이다. 텍스트 노드를 무시하기 위해서는 반드시 타입 3(텍스트 노드)와 8(주석 노드)를 체크해야 한다.

XML:
  <?xml version="1.0"?>   
  <myXMLdoc xmlns:myns="https://myfoo.com"> 
    <myns:foo>bar</myns:foo> 
  </myXMLdoc>

JavaScript: 
  var myXMLDoc = getXMLDocument().documentElement; 
  var myChildren = myXMLDoc.childNodes; 

  for (var run = 0; run < myChildren.length; run++){ 
    if ( (myChildren[run].nodeType != 3) &&
          myChildren[run].nodeType != 8) ){ 
      // not a text or comment node 
    };
  };

더 자세한 사항과 해결방안은 다음을 참고하라: Whitespace in the DOM

XML 데이터 아일랜드

IE는 XML 데이터 아일랜드라 불리우는 비표준 기능을 가지고 있는데 이것은 비표준 HTML 태그인 <xml> 을 사용하여 HTML 문서내에 XML을 포함할 수 있게 한다. Mozilla는 XML 데이터 아일랜드를 지원하지 않으며 이것을 인식되지 않는 HTML 태그로 취급한다. 같은 기능을 XHTML을 사용하여 이룰 수 있지만, IE의 XHTML 지원은 미약하기 때문에 이것은 보통 추가적인 것은 아니다.

IE의 XML 데이터 아일랜드:

<xml id="xmldataisland"> 
  <foo>bar</foo> 
</xml>

크로스 브라우징 해결 방법 중의 하나는 DOM 파서를 이용하는 것인데 이것은 직렬화된 XML 문서를 포함한 문자열을 파싱하고 파싱된 XML에 대한 문서를 생성한다. Mozilla는 DOMParser 오브젝트를 사용하며, 이는 직렬화된 문자열을 가지고 외부로 XML 문서를 생성한다. IE에서는 같은 기능을 ActiveX를 사용하여 만들수 있다. new ActiveXObject("Microsoft.XMLDOM")를 사용하여 생성한 오브젝트는 문자열을 가지고 문서를 생성하는 loadXML 메소드를 가진다. 다음 코드가 그 방법을 보여준다:

 var xmlString = "<xml id=\"xmldataisland\"><foo>bar</foo></xml>"; 
 var myDocument; 
 if (document.implementation.createDocument){ 
   // Mozilla, create a new DOMParser 
   var parser = new DOMParser(); 
   myDocument = parser.parseFromString(xmlString, "text/xml"); 
 } else if (window.ActiveXObject){ 
   // Internet Explorer, create a new XML document using ActiveX 
   // and use loadXML as a DOM parser. 
   myDocument = new ActiveXObject("Microsoft.XMLDOM"); 
   myDocument.async="false"; 
   myDocument.loadXML(xmlString);
 }

</pre>

다른 대안은 다음을 참고하라: Using XML Data Islands in Mozilla

XML HTTP request

IE는 MSXML의 XMLHTTP 클래스를 사용하여 XML 파일을 보내거나 탐색할 수 있게 하는데, 이것은 new ActiveXObject("Msxml2.XMLHTTP") 또는 new ActiveXObject("Microsoft.XMLHTTP")를 사용한 ActiveX를 통해 인스턴스화 된다. 이러한 것에 대해 표준이 존재하지 않기 때문에, Mozilla는 같은 기능에 대해 전역 자바스크립트 객체인 XMLHttpRequest에서 이를 제공한다. IE도 역시 버전 7 부터는 원시 XMLHttpRequest 오브젝트를 지원한다.

new XMLHttpRequest()를 사용하여 오브젝트를 인스턴스화 한 뒤에는 어떤 타입의 요청(GET 혹은 POST)을 사용할 것인지, 어느 파일을 로드할 것인지, 비동기인지 아닌지를 지정하기 위한 open 메소드를 사용할 수 있다. 만약 호출이 비동기이면 onload 멤버에 함수 레퍼런스를 준다. 이것은 요청이 완료 되었을때 한번 호출된다.

동기 요청:

  var myXMLHTTPRequest = new XMLHttpRequest(); 
  myXMLHTTPRequest.open("GET", "data.xml", false); 

  myXMLHTTPRequest.send(null); 

  var myXMLDocument = myXMLHTTPRequest.responseXML; 

비동기 요청:

  var myXMLHTTPRequest; 

  function xmlLoaded() { 
    var myXMLDocument = myXMLHTTPRequest.responseXML; 
  }

  function loadXML(){ 
    myXMLHTTPRequest = new XMLHttpRequest();

    myXMLHTTPRequest.open("GET", "data.xml", true);

    myXMLHTTPRequest.onload = xmlLoaded; 

    myXMLHTTPRequest.send(null); 
  }

표 7은 Mozilla의 XMLHttpRequest</code에 대해 사용가능한 메소드와 속성들의 리스트이다.

표 7. XMLHttpRequest methods and properties
Name Description
void abort() Stops the request if it is still running.
string getAllResponseHeaders() Returns all response headers as one string.
string getResponseHeader(string headerName) Returns the value of the specified header.
functionRef onerror If set, the references function will be called whenever an error occurs during the request.
functionRef onload If set, the references function will be called when the request completes successfully and the response has been received. Use when an asynchronous request is used.
void open (string HTTP_Method, string URL)

void open (string HTTP_Method, string URL, boolean async, string userName, string password)
Initializes the request for the specified URL, using either GET or POST as the HTTP method. To send the request, call the send() method after initialization. If async is false, the request is synchronous, else it defaults to asynchronous. Optionally, you can specify a username and password for the given URL needed.
int readyState State of the request. Possible values:
Value Description
0 UNINITIALIZED - open() has not been called yet.
1 LOADING - send() has not been called yet.
2 LOADED - send() has been called, headers and status are available.
3 INTERACTIVE - Downloading, responseText holds the partial data.
4 COMPLETED - Finished with all operations.
string responseText String containing the response.
DOMDocument responseXML DOM Document containing the response.
void send(variant body) Initiates the request. If body is defined, it is sent as the body of the POST request. body can be an XML document or a string serialized XML document.
void setRequestHeader (string headerName, string headerValue) Sets an HTTP request header for use in the HTTP request. Has to be called after open() is called.
string status The status code of the HTTP response.

XSLT 차이

Mozilla는 XSL 변환 (XSLT) 1.0을 지원한다. Mozilla는 또한 자바스크립트로 XSLT 변환을 실행하는 것을 지원하고 문서상에서 XPath를 실행 하는 것도 지원한다.

Mozilla에서는 XML 이나 XSLT 파일을 보낼때 XML mimetype (<code>text/xml or application/xml)을 사용해야 한다. 이것이 왜 XSLT가 Mozilla에서는 실행되지 않는데 IE에서는 실행되는 가에 대한 가장 일반적인 이유이다. Mozilla는 이런식으로 엄격하다.

IE 5.0과 5.5는 XSLT의 working draft를 지원했는데 이것은 final 1.0 recommendation과는 상당히 차이가 있었다. XSLT가 어느 버전으로 쓰였는지 구별할 수 있는 가장 쉬운 방법은 네임스페이스를 보는 것이다. 1.0 권고안의 네임스페이스는 https://www.w3.org/1999/XSL/Transform인 반면, working draft의 네임스페이스는 https://www.w3.org/TR/WD-xsl이다. IE 6은 하위 호환성을 위하여 working draft를 지원한다. 그러나 Mozilla는 working draft를 지원하지 않고 최종 권고안만을 지원한다.

만약 XSLT에서 브라우저를 구별해야 한다면 "xsl:vendor" 시스템 속성으로 알아낼 수 있다. Mozilla의 XSLT엔진은 "Transformiix"라고 표시하겠지만 IE는 "Microsoft"를 반환할 것이다.

<xsl:if test="system-property('xsl:vendor') = 'Transformiix'"> 
  <!-- Mozilla specific markup --> 
</xsl:if> 
<xsl:if test="system-property('xsl:vendor') = 'Microsoft'"> 
  <!-- Internet Explorer specific markup --> 
</xsl:if> 

Mozilla는 XSLT에 대한 자바스크립트 인터페이스도 지원하며 이것은 웹사이트가 메모리 상에서 XSLT 변환을 완료할 수 있게 한다. 이것은 자바스크립트 전역 오브젝트인 XSLTProcessor를 사용하여 할 수 있다. XSLTProcessor는 XML과 XSLT 파일을 로드해야 하는데, 이것은 DOM 도큐먼트가 필요하기 때문이다. XSLTProcessor에 의해 임포트된 XSLT 문서는 XSLT 파라미터들을 조작할 수 있게 한다.

XSLTProcessor 는 transformToDocument()를 사용하여 단독 도큐먼트를 생성하거나 transformToFragment()를 사용하여 도큐먼트 프래그먼트를 생성할 수 있다. 이것은 다른 DOM 문서에 쉽게 추가할 수 있다. 다음의 예를 보자:

var xslStylesheet; 
var xsltProcessor = new XSLTProcessor(); 

// load the xslt file, example1.xsl 
var myXMLHTTPRequest = new XMLHttpRequest(); 
myXMLHTTPRequest.open("GET", "example1.xsl", false); 
myXMLHTTPRequest.send(null); 

// get the XML document and import it 
xslStylesheet = myXMLHTTPRequest.responseXML; 

xsltProcessor.importStylesheet(xslStylesheet); 

// load the xml file, example1.xml 
myXMLHTTPRequest = new XMLHttpRequest(); 
myXMLHTTPRequest.open("GET", "example1.xml", false); 
myXMLHTTPRequest.send(null); 

var xmlSource = myXMLHTTPRequest.responseXML; 

var resultDocument = xsltProcessor.transformToDocument(xmlSource); 

XSLTProcessor를 생성한 후에는 XMLHttpRequest를 사용하여 XSLT 파일을 로드한다. XMLHttpRequest의 responseXML 멤버는 XSLT파일의 XML 문서를 포함하는데, 이는 importStylesheet로 전달된다. 그리고 나서 XMLHttpRequest를 다시 사용하여 변환되어야 하는 원본 XML 문서를 로드한다. 이 문서는 이제 XSLTProcessortransformToDocument 멤버로 전달된다. 표 8은 XSLTProcessor 메소드의 리스트이다.

표 8. XSLTProcessor methods
Method Description
void importStylesheet(Node styleSheet) Imports the XSLT stylesheet. The styleSheet argument is the root node of an XSLT stylesheet's DOM document.
DocumentFragment transformToFragment(Node source, Document owner) Transforms the Node source by applying the stylesheet imported using the importStylesheet method and generates a DocumentFragment. owner specifies what DOM document the DocumentFragment should belong to, making it appendable to that DOM document.
Document transformToDocument(Node source) Transforms the Node source by applying the stylesheet imported using the importStylesheet method and returns a standalone DOM document.
void setParameter(String namespaceURI, String localName, Variant value) Sets a parameter in the imported XSLT stylesheet.
Variant getParameter(String namespaceURI, String localName) Gets the value of a parameter in the imported XSLT stylesheet.
void removeParameter(String namespaceURI, String localName) Removes all set parameters from the imported XSLT stylesheet and makes them default to the XSLT-defined defaults.
void clearParameters() Removes all set parameters and sets them to defaults specified in the XSLT stylesheet.
void reset() Removes all parameters and stylesheets.

원래 문서 정보

문서 태그 및 공헌자

태그: 
 이 페이지의 공헌자: teoli, Jayvdb, krusch, Netaras, Redleaf, Sebuls, taggon
 최종 변경: teoli,