결정적인 차이는(?!) prototype과 달리 dojo는 'on'을 항상 붙여야 한다(예: onclick, onchange)는 것이다. dojo의 위젯(dijit)들은 이벤트 이름을 대소문자를 섞어서 사용해서(예: onClick, onChange) 표준 이벤트들과 구별한다.
사실 dojo.connect()는 이벤트 핸들러 연결보다 더 많은 일을 한다. 실제 구현은 AOP의 before advice에 가깝다고 볼 수 있다. 즉, 일반적인 함수에 대해서도 적용 가능하다.
BOM(Browser Object Model) 코드는... 열라 길다. -.-; 생략할려다가... prototype이나 dojo가 얼마나 많은 노가다를 줄여주는지 확인하는 차원에서 주욱 적어봤다. prototype과 dojo 코드는 얼추 비슷해 보이지만, 가만히 살펴보면 자질구레한 부분에서 조금씩 다르다:
* BOM
var xhr; try { xhr = new XMLHttpRequest(); } catch (e) { try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { // ... Orz } } } xhr.onstatechange = function() { select (xhr.readyState) { case 4: // loaded select (xhr.statusCode) { case 200: // ok break; case ... } case ... } } xhr.open('GET','your/url', true); xhr.send('paramName1=' + encodeURIComponent(paramValue1) + '¶mName2=' + encodeURIComponent(paramValue)); ...
요청 메소드를 파라메터로 처리하지 않고, 요청 메소드별로 함수가 따로 있다(코멘트 부분 참조).
요청 url을 별도의 파라메터가 아니라 다른 옵션들과 똑같이 취급한다.
동기/비동기 모드를 지정하는 파라메터가 거꾸로다(당연히 이름도 asynchronous가 아니고 sync다).
응답 형식을 지정할 수 있으며, 응답이 바로 콜백함수로 전달된다.(즉, json 응답의 처리 방법이 다르다.)
prototype처럼 성공/실패 여부에 따라 콜백 함수를 지정할 수도 있지만, 내 경우에는 dojo.Deferred(twisted의 deferred와 유사한데...)를 선호한다. 여기서는 많은 옵션들을 생략했는데, 자세한 것은 각각의 온라인 문서를 찾아보시라.
Ajax.Updater / Ajax.PeriodicalUpdater에 해당하는 녀석은 없다. 그냥 window.setInterval()과 domNode.innerHTML을 쓰면 되니까 그다지 아쉽지 않다. 그리고, dojo의 위젯(dijit) 중에 ContentPane이라는 녀석을 쓰면 이 모든걸 한 줄로 끝낼 수 있다.
dojo에는 XHMLHttpRequest 대신 <script>태그와 <iframe>태그를 사용하는 dojo.io.script와 dojo.io.iframe이라는 두개의 특별한 녀석들이 있다. AJAX의 Cross Domain 제한을 경험해본 개발자라면 귀가 솔깃할 만한 녀석들이다. 자세한 것은 역시 온라인 문서를 찾아보시라.
유틸리티 함수들을 살펴보자. dojo에는 아쉽게도(?) prototype사용자들이 제일 좋아하는 함수 $()가 없다.
대신 dojo.byId()가 있다. 이게 귀찮다고 생각하시는 분이 계시겠지만 dojo 개발팀에서도 꽤 오랜 고민과 토론 끝에
내린 결론이다. 관심있는 분은 메일링을 뒤져보시라.
* 지정한 id를 가진 DOM node를 검색
* dom
var node = document.getElementById('abc');
* prototype
var node = $('abc');
* dojo
var node = dojo.byId('abc');
너무 길다고? 익숙해지면 별 차이없다. document.getElementById()보다는 짧지않은가! 거기다 나는 $ 기호에 알르레기반응이 있다. per~~~~~l 씨러=3=3=3=33
* 지정한 노드 이름(태그 이름) / CSS 셀렉터를 가진 DOM node들(배열)을 검색
* dom
var nodes = document.getElementsByTagName('div');
* prototype
var nodes = $$('div');
var nodes = $$('.item');
var nodes = $$('#title);
var nodes = $$('div.item');
...
* dojo
var nodes = dojo.query('div');
var nodes = dojo.query('.item');
var nodes = dojo.query('#title');
var nodes = dojo.query('div.item');
...
dojo.query()도 prototype이나 jquery와 비슷한 CSS 2.1 셀렉터를 지원한다. 더 자세한 내용은 온라인 문서를 찾아보시라.
나중에 얘기하겠지만 prototype에서 $$와 each()의 결합을 많이 쓰는 것처럼, dojo.query()도forEach()와 함께 쓰면 편리하다.
제목은 거창하게 "prototype 사용자를 위한 dojo 입문"이지만... 글쎄... 그냥... dojo 0.4 이전 버전의 dojo에서 실망하거나 좌절하고, 두번 다시는 dojo를 거들떠 보지 않는 분들에게... dojo도 꽤 쓸만하다는(쓸만해졌다는?) 얘기를 하고 싶었다.
제대로 될지는 모르겠지만, 일단 시작해보자!
제 1 장 getting dojo
prototype은 홈페이지에서 prototype.js를 받아서 로컬 웹서버에 올려놓고 참조했다. dojo도 마찬가지다.
주의: 할 점은 dojo가 두 번 들어간다는 것이다. 내 경우엔 js/dojo에 dojo를 풀었더니 무려 js/dojo/dojo/dojo.js가 되었다. -.-;;;
그러나 120k짜리 js파일(1.6은 120K)만 받으면 되는 prototype에 익숙한 개발자들에게 3M를 훌쩍 넘는 dojo의
zip파일(1.0은 3.9M)은 압박(!) 그 자체이다. 내가 알고 있는 많은 개발자들이 여기에서 좌절하고...
prototype으로 돌아간다.
그런 분들을 위해 미리 말해두면 prototype 대체용의 dojo라면 잡다한 다른 파일 필요없이 아래의 파일 중에 하나만 받아서 쓰면 된다: