개인적으로 함께 작업하기 가장 편안한 JavaScript 라이브러리인 jQuery가 벌써 공개 2주년을 맞이하였다.
이를 기념해서 새로운 버전 1.2.2가 발표되었는데, 바뀐 주요 내용으로 몇몇 버그 수정과 함께 가장 많이 사용되는 DOM element를 jQuery 함수로 전달하는 과정이, 예를 들어 $(DOMElement), 3 배나 더 빨라졌다고 한다.

이 밖에도, .ready() 함수의 경우 Internet Explorer에서의 기능 구현이 개선되었고, 이젠 모든 브라우저가 DOM을 다 읽어들일 때까지 기다리는 것이 아니라 CSS까지 마저 읽어올 때까지 기다려 준단다. 이것은 보통 특정 요소의 스타일을 변경하고 싶을 떄, 어차피 웹 브라우저가 CSS 파일을 먼저 해석해야 하기 때문에 바뀐 변화인 듯.
그리고, .hover()는 이제 새로운 mouseentermouseleave 이벤트로 분리되었다. 참고로, 이놈들은 하위 요소들에도 함께 적용되는 mouseover와 mouseout과는 차별되서, 해당 요소에만 적용된다.
또, 새로 추가된 Mouse Wheel plugin이 소개되었다. 사용 예:

$("div").bind("mousewheel", function(eventdelta) {
  if ( delta < 0 )
    $(this).append("up");
  else
    $(this).append("down");
});

:not() selector의 사용 용법도 다양해져서, 다음과 같은 작업도 가능해졌다:

$(".hover:not(li.active)")
$("li:not(.active,.hover,:contains(test))")

무척 복잡해 보이지만, 그 사용 목적은 아주 명확하고 세밀해졌다.

일반 jQuery Ajax 작업에도 변화가 있어서, 덤으로 서버에 Accept header 정보도 함께 전달하면서, 원하는 종류의 데이타를 선택적으로 불러올 수 있게 되었다.

매번 생각하지만, jQuery는 개발자들을 위한 두통 완화제일지도.

IE에게 웹 표준을 잘 인식하도록 최면을 거는 IE7 JavaScript 라이브러리가 2.0(beta) 버전으로 갱신되었다. IE7.js v2.0(beta)의 자세한 갱신 내용은 개발자의 웹 블로그의 글에 올려져 있는데, 주요 내용은 다음과 같다.

  • 이제 IE7 프로젝트는 googlecode로 자리를 옮겨서 진행됨.
  • 이제 IE7은 모듈러(modular) 형태로 배포되지 않고, 크게 IE7.js와 IE8.js 파일로 분리되서 배포됨.
  • IE7.js는 실제 MSIE7 브라우저에 포함되어 있는 기능들만을 인식하게 고쳐줌.
  • 기타 모든 기능 개선은 IE8.js로 옮김.
  • IE7의 파일 크기 축소(11KB gzipped).
  • IE7의 실행 속도 향상.
  • blank.gif 파일을 제외하고 다른 모든 의존적 추가 파일들이 필요없게 됨.
  • Google 서버를 통해 IE7/IE8.js 파일들을 바로 링크할 수 있게 됨.
  • base64로 인코딩된 그림을 위한 기능 수정은 더 이상 포함되지 않음.

간단하게 각각의 IE 6와 IE 7 브라우저를 위한 기능의 분화가 있으면서 파일도 둘로 나뉘게 되었다.
실제 웹 페이지의 적용은 이제, 라이브러리 관련 파일들을 서버에 올려둘 필요없이, 간단하게 <head>에 다음과 같이 써주면 끝.

MSIE5-6 웹 브라우저를 MSIE7처럼 행동하도록 기능을 갱신하려면,

<!--[if lt IE 7]>
<script src="http://ie7-js.googlecode.com/svn/version/xx.x/IE7.js" type="text/javascript"></script>
<![endif]-->

또는, MSIE5-7 웹 브라우저를 포함해서 MSIE7가 지원하지 않는 몇몇 CSS selectors와 속성들을 인식하도록 하려면 다음과 같이 써준다.

<!--[if lt IE 8]>
<script src="http://ie7-js.googlecode.com/svn/version/xx.x/IE8.js" type="text/javascript"></script>
<![endif]-->

아무쪼록, 나중에 IE 8이 발표되면서 또 하나의 IE9.js 파일이 등장하지 않았으면 한다.

웹 개발 과정에 있어서 웹 페이지 속 UI 동작을 구현하는데 필요한 기본적인 기능들을 모아놓은 JavaScript Library들이 제공되면서 개발자들의 손을 한 시름 덜어주게 되었고, 결국 남은 여력을 프로젝트에 더 집중하게 되면서 작업의 효율성을 증가시켜 주었듯이, 마찬가지로 웹 페이지의 기본 layout을 잡을 때 반복적으로 수행되던 CSS 작업에서도 빠른 작업 수행 속도를 붙여줄 수 있는 framework 형태의 여러 조력자들이 등장하고 있다.

개인적으로 JavaScript Library로는 jQuery를 그리고 CSS framework로는 blueprintcss를 주로 사용하게 되면서, 예전에 공개했던 HTML 문서 생성을 위한 TextMate용 snippet에도 작은 변화가 있었다.
여기에 그 바뀐 내용을 공개하면, 우선 아래는 HTML 4.01 Strict DocType을 위해 “page4” tab trigger로 지정된 HTML snippet이다.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ko" dir="ltr">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>${1:Title}</title>
    ${2:<link rel="stylesheet" href="${3:css/blueprint/}screen.css" type="text/css" media="screen, projection" />
    <link rel="stylesheet" href="$3print.css" type="text/css" media="print" />
    <!--[lt IE 7]><link rel="stylesheet" href="$3lib/ie.css" type="text/css" media="screen, projection"><![endif]-->
    }<style type="text/css" media="screen">
    /* <![CDATA[ */
 
    /* ]]> */
    </style> 
    ${4:<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
    }<script type="text/javascript">
    // <![CDATA[ 
        $0
    // ]]> 
    </script> 
  </head>
  <body id="${5:page}">
    <div class="container">
      <div class="column span-${6:24}">
        <h1>${7:Header}</h1>
      </div>
      <div class="column span-${8:20}">
        ${9:Main content}
      </div>
      <div class="column span-${10:4} last">
        ${11:Right sidebar}
      </div>
      ${12:<div class="column span-24">
        ${13:Footer}
      </div>}
    </div>
  </body>
</html>

기본적으로 지정되어 있는 HTML 문서의 구조는, 오른쪽에 작은 sidebar가 위치한 보편적인 2 column 구조로 위 아래에 Header와 Footer가 위치하고 있다.

다음은 같은 구조를 가진 XHTML 1.0 Strict DocType 문서를 위한 HTML snippet. tab trigger로 “page”가 지정되어 있다.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" ${1:${2:xml:lang="ko"}${3: lang="ko"}} dir="ltr">
  <head>
    <meta http-equiv="Content-Type" content="${4:application/xhtml+xml}; charset=utf-8" />
    <title>${5:Title}</title>
    ${6:<link rel="stylesheet" href="${7:css/blueprint/}screen.css" type="text/css" media="screen, projection" />
    <link rel="stylesheet" href="$7print.css" type="text/css" media="print" />
    <!--[lt IE 7]><link rel="stylesheet" href="$7lib/ie.css" type="text/css" media="screen, projection"><![endif]-->
    }<style type="text/css" media="screen">
    /* <![CDATA[ */
 
    /* ]]> */
    </style> 
    ${8:<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
    }<script type="text/javascript">
    // <![CDATA[ 
      $0
    // ]]> 
    </script> 
  </head>
  <body id="${9:page}">
   <div class="container">
      <div class="column span-${10:24}">
        <h1>${11:Header}</h1>
      </div>
      <div class="column span-${12:20}">
        ${13:Main content}
      </div>
      <div class="column span-${14:4} last">
        ${15:Right sidebar}
      </div>
      ${16:<div class="column span-24">
        ${17:Footer}
      </div>}
    </div>
  </body>
</html>

간단한 것이지만, 손놀림을 덜 수 있는 또 하나의 꼼수다.

  • IE에서는 event listeners를 붙이거나 없앨 때, addEventListener/removeEventListener 대신에, attachEvent/detachEvent를 쓴다.
  • IE에서는 event 이름의 형식이, event가 아닌, onevent 형식을 쓴다.
  • IE에서는 event object를 해당 listener의 한 전달 변수(argument)로 돌려주지 않아서, 대신 global event 변수를 써서 접근해야 한다.
  • event 발생시 기본적으로 주어진 action이 실행되는 것을 막으려면 preventDefault method를 쓰는 것이 정석이지만, IE에서는 event object의 returnValue 속성 값을 false로 지정해 주어야 한다.
  • IE는 event 전달 과정(propagation) 중에서 보통 맨 처럼 진행되는 capture phase를 지원하지 않는다.
  • 다른 객체들로의 event 전달 과정을 멈추려면, stopPropagation method를 쓰는 대신에, event object의 cancelBubble 속성 값을 true로 지정해 줘야 한다.
  • IE에서는 event listeners를 method가 아닌 독립된 function으로 불러와서, event를 일으킨 target element를 알아볼 때 간단한 this 키워드를 쓸 수가 없고, 대신에 여러 단계의 상당히 복잡한 과정을 거처야만 얻을 수 있다.

    if (typeof element.addEventListener != "undefined") {
      element.addEventListener("event", eventListener, false);
    } else if (typeof element.attachEvent != "undefined") {
      var thisListener = function() {
        var event = window.event;
        if (Function.prototype.call) {
          eventListener.call(element, event);
        } else {
          target._currentListener = eventListener;
          target._currentListener(event);
          target._currentListener = null;
        }
      };
      element.attachEvent("onevent", thisListener);
    }
  • IE에서는 어느 한 element의 event listener가 DOM에 속해있는 또 다른 node의 reference를 포함하고 있을 경우, 사용자가 다른 페이지로 이동하더라도 해당 listener와 함께 관련된 DOM node들이 메모리에서 지워지지 않고 상주하게 된다. (IE 6의 memory leak 현상은 근래에 있었던 보안 패치에도 불구하고 여전한 듯.)

프휴~ 🙁

jQuery 1.2 발표후 보고된 자질한 버그들을 잽싸게 잡으면서 jQuery 1.2.1이 배포되고 있다.
벌레 잡기와 함께 바뀐 주요 변경 내용은, 새로 추가되었던 상대적 애니메이션 효과의 API가 기존 애니메이션 스타일과 충돌을 일으키는 문제를 해결하면서 상대적 애니메니션 효과의 문법이 아래처럼 약간 바뀌었다.

$(...).animate({ height: "+=50px", width: "-=20%", fontSize: "+=2em" });

위에서, +=는 현재 위치에서 더하고, -=는 현재의 위치에서 값을 빼라는 의미로 사용.

그리고 대체 용법을 제공하면서 사라졌던 .eq() method가 다시 추가되었다. 여기에는 많은 플러그인들이 그 동안 .eq() method를 많이 써왔다는 점과, 기존에 이것을 대체하려고 했던 .slice()가 이 경우 자연스런 해법이 아닌 것 같아서 삭제가 재고되었단다.

1.2 발표 후, 연이어 급히 벌레 잡는 발표로 불안한 인상을 주기도 하지만 그 만큼 더 안정화 되었다고 믿고 싶다.

한편, 얼마 전에 예고되었듯이 jQuery UI가 공식 페이지와 함께 공개되기 직전인가보다.
아직 공식 발표 소식은 없지만, 잠깐 데모를 살펴봤는데 Safari에서는 몇몇 동작이 제대로 동작하지 않는 등, 아직 개발이 활발히 진행중인 상태라 실제 적용에는 아직 무리가 있는 듯 하지만, 앞으로 분명 UI 개발자들에게 다양한 선택의 폭을 넓혀주리라 믿는다.

jQuery UI demo window
데모 어플리케이션 중에, JavaScript Speed Test 어플리케이션을 Safari에서 열어보면 여지없이 Safari가 뻗어버려서 주의가 요구됨. 😳