티스토리 뷰
자바스크립트로 코딩 좀 했다는 분들도 IE(참고자료)와 불여우, 그리고 W3C의 표준 DOM 이벤트 모델간의 차이에 대해서 제대로 이해하기보다는 까이꺼~ 대충~ 통밥으로~ 처리하는 경우를 많이 본다. 누가 좋으냐 나쁘냐는 논쟁은 끝이 없으니... 넘어가기로 하고... 골치아픈 브라우져간의 차이점을 신경쓰지 않고 개발할 수 있는 dojo의 이벤트 시스템을 알아보자.
보시다시피 단순하다.
기존 방식대로 하면:
어랏?! 더 단순하자나! 그러나 이 코드가 항상 동작하는 것이 아니다라는 점이 문제다. 기존의 방식에 익숙하다면 지금 당장 바꿀 필요는 없다. dojo.connect가 있다는 점만 기억해두면 머지않아 필요할때가 올 것이다. 하나 이상의 이벤트 핸들러를 연결해야할 때, 이벤트 핸들러에서 이벤트의 전달을 중단해야 할 때, 또는 기본 동작(폼 submit같은)을 막고 싶을 때... 등등...
dijit(dojo의 위젯 시스템)을 쓴다면 별도로 disconnect를 해줄 필요가 없지만, 그 외의 경우에는 꼼꼼하게 disconnect해주는 것이 좋다. DOM 노드를 제거할때 dojo._destroyElement()를 사용하면 자동으로 연관된 이벤트 핸들러들을 disconnect 해주므로 편리하게 쓸 수 있다.
script태그가 body태그 끄트머리에 들어가있는 것이 이상하다고 생각한 분 계신가? 그렇다. 일부러 그렇게 한거다. 저렇게 안하면 브라우져와 주변 상황에 따라(!) 예상치 못한 결과를 만나게 된다. 그래서 dojo에서 이런 방법을 제공한다:
예제가 좀 길어졌지만, 기존에 자바스크립질에 익숙한 분들은 dojo.addOnLoad/Unload가 body의 onload/onunload핸들러와 크게 다르지 않다는 것을 알아챘을 것이다. 즉, <body onload="init()" onunload="destroy()"> 이라고 하면 된다는 얘기~ 그런데 왜 저렇게 복잡하게 하느냐고? 예전에도 한번 포스팅한 적이 있는데... onload의 타이밍이 미묘해서 브라우져마다 조금씩 다르다.
좀 다른 얘기지만, 위의 예제 코드에서 init()/destroy()에서 사용된 배열에 이벤트 핸들들을 보관해두고 일괄 해제하는 패턴은 자주 사용되므로 익해두면 편하다.
보너스로 한가지 더:
자바스크립트에 익숙한 분들은 return false; 이런 짓(!)을 하시는데... 이거 생각처럼 잘 안된다. 이 기회에 링크한 문서들을 참고해서 왜 되고 또 왜 안되는지 좀 더 파 보시는 것도 괜찮을 듯...
다소 뜬금없지만, 이벤트 시스템의 일부이기도 하고, 유용한 녀석들이니 언급은 하고 넘어가야 할 것 같다:
다음은 dojo의 객체 시스템에 대해서 알아보기로 하고...
오늘은... 이만...
정말... 덥다...
- dojo.connect(이벤트객체, 이벤트이름, 이벤트핸들러함수) : 지정한 객체에서 지정한 이름의 이벤트가 발생하면 이벤트 핸들러 함수를 호출하도록 "연결"한다. 핸들을 리턴한다.
- dojo.disconnect(핸들) : dojo.connect()함수의 리턴값으로 받은 핸들을 사용하여 이벤트와 이벤트 핸들러 함수의 연결을 끊는다.
<html>
<head>
<script type="text/javascript" djConfig="isDebug:true" src="http://o.aolcdn.com/dojo/1.1.1/dojo/dojo.xd.js"></script>
<script type="text/javascript">
</script>
</head>
<body>
<button id="helloBtn">Click Me</button>
<script type="text/javascript">
var helloBtn_onclick = function(evt) {
alert('hello, world!');
if (helloBtn_onclick_handler) {
dojo.disconnect(helloBtn_onclick_handler);
helloBtn_onclick_handler = null;
}
};
var helloBtn = dojo.byId('helloBtn');
var helloBtn_onclick_handler = dojo.connect(helloBtn, 'onclick', helloBtn_onclick);
</script>
</body>
</html>
<head>
<script type="text/javascript" djConfig="isDebug:true" src="http://o.aolcdn.com/dojo/1.1.1/dojo/dojo.xd.js"></script>
<script type="text/javascript">
</script>
</head>
<body>
<button id="helloBtn">Click Me</button>
<script type="text/javascript">
var helloBtn_onclick = function(evt) {
alert('hello, world!');
if (helloBtn_onclick_handler) {
dojo.disconnect(helloBtn_onclick_handler);
helloBtn_onclick_handler = null;
}
};
var helloBtn = dojo.byId('helloBtn');
var helloBtn_onclick_handler = dojo.connect(helloBtn, 'onclick', helloBtn_onclick);
</script>
</body>
</html>
보시다시피 단순하다.
기존 방식대로 하면:
helloBtn_onclick = function(evt) {
alert('hello, world!');
helloBtn.onclick = null;
};
var helloBtn = document.getElementById('helloBtn');
helloBtn.onclick = helloBtn_onclick;
alert('hello, world!');
helloBtn.onclick = null;
};
var helloBtn = document.getElementById('helloBtn');
helloBtn.onclick = helloBtn_onclick;
어랏?! 더 단순하자나! 그러나 이 코드가 항상 동작하는 것이 아니다라는 점이 문제다. 기존의 방식에 익숙하다면 지금 당장 바꿀 필요는 없다. dojo.connect가 있다는 점만 기억해두면 머지않아 필요할때가 올 것이다. 하나 이상의 이벤트 핸들러를 연결해야할 때, 이벤트 핸들러에서 이벤트의 전달을 중단해야 할 때, 또는 기본 동작(폼 submit같은)을 막고 싶을 때... 등등...
dijit(dojo의 위젯 시스템)을 쓴다면 별도로 disconnect를 해줄 필요가 없지만, 그 외의 경우에는 꼼꼼하게 disconnect해주는 것이 좋다. DOM 노드를 제거할때 dojo._destroyElement()를 사용하면 자동으로 연관된 이벤트 핸들러들을 disconnect 해주므로 편리하게 쓸 수 있다.
script태그가 body태그 끄트머리에 들어가있는 것이 이상하다고 생각한 분 계신가? 그렇다. 일부러 그렇게 한거다. 저렇게 안하면 브라우져와 주변 상황에 따라(!) 예상치 못한 결과를 만나게 된다. 그래서 dojo에서 이런 방법을 제공한다:
- dojo.addOnLoad(핸들러함수) : 페이지를 열고 난 직후에 호출될 핸들러 함수를 추가한다.
- dojo.addOnUnload(핸들러함수) : 페이지를 닫기 직전에 호출될 핸들러 함수를 추가한다.
<html>
<head>
<script type="text/javascript" djConfig="isDebug:true" src="http://o.aolcdn.com/dojo/1.1.1/dojo/dojo.xd.js"></script>
<script type="text/javascript">
var helloBtn_onclick = function(evt) {
alert('hello, world!');
};
var byeBtn_onclick = function(evt) {
alert('bye~ world!');
location.href = 'http://google.com/';
};
var handlers = [];
var init = function() {
handlers.push(dojo.connect(dojo.byId('helloBtn'), 'onclick', helloBtn_onclick));
handlers.push(dojo.connect(dojo.byId('byeBtn'), 'onclick', byeBtn_onclick));
};
var destroy = function() {
dojo.forEach(handlers).disconnect();
}
dojo.addOnLoad(init);
dojo.addOnUnload(destroy);
</script>
</head>
<body>
<button id="helloBtn">Click Me</button>
<button id="byeBtn">Bye~</button>
</body>
</html>
<head>
<script type="text/javascript" djConfig="isDebug:true" src="http://o.aolcdn.com/dojo/1.1.1/dojo/dojo.xd.js"></script>
<script type="text/javascript">
var helloBtn_onclick = function(evt) {
alert('hello, world!');
};
var byeBtn_onclick = function(evt) {
alert('bye~ world!');
location.href = 'http://google.com/';
};
var handlers = [];
var init = function() {
handlers.push(dojo.connect(dojo.byId('helloBtn'), 'onclick', helloBtn_onclick));
handlers.push(dojo.connect(dojo.byId('byeBtn'), 'onclick', byeBtn_onclick));
};
var destroy = function() {
dojo.forEach(handlers).disconnect();
}
dojo.addOnLoad(init);
dojo.addOnUnload(destroy);
</script>
</head>
<body>
<button id="helloBtn">Click Me</button>
<button id="byeBtn">Bye~</button>
</body>
</html>
예제가 좀 길어졌지만, 기존에 자바스크립질에 익숙한 분들은 dojo.addOnLoad/Unload가 body의 onload/onunload핸들러와 크게 다르지 않다는 것을 알아챘을 것이다. 즉, <body onload="init()" onunload="destroy()"> 이라고 하면 된다는 얘기~ 그런데 왜 저렇게 복잡하게 하느냐고? 예전에도 한번 포스팅한 적이 있는데... onload의 타이밍이 미묘해서 브라우져마다 조금씩 다르다.
좀 다른 얘기지만, 위의 예제 코드에서 init()/destroy()에서 사용된 배열에 이벤트 핸들들을 보관해두고 일괄 해제하는 패턴은 자주 사용되므로 익해두면 편하다.
보너스로 한가지 더:
- dojo.stopEvent(이벤트객체) : 이벤트의 전파와 기본 동작을 모두 차단한다.
<form id="loginForm" action="login.do" method="post">
<input type="text" id="usernameText" name="username" value="" />
<input type="password" id="passwordText" name="password" value="" />
<button type="submit">Login</button>
</form>
<script>
dojo.connect(dojo.byId('loginForm'), 'onsubmit', function(evt) {
if (!dojo.byId('usernameText').value || !dojo.byId('passwordText').value) {
dojo.stopEvent(evt);
}
});
</script>
<input type="text" id="usernameText" name="username" value="" />
<input type="password" id="passwordText" name="password" value="" />
<button type="submit">Login</button>
</form>
<script>
dojo.connect(dojo.byId('loginForm'), 'onsubmit', function(evt) {
if (!dojo.byId('usernameText').value || !dojo.byId('passwordText').value) {
dojo.stopEvent(evt);
}
});
</script>
자바스크립트에 익숙한 분들은 return false; 이런 짓(!)을 하시는데... 이거 생각처럼 잘 안된다. 이 기회에 링크한 문서들을 참고해서 왜 되고 또 왜 안되는지 좀 더 파 보시는 것도 괜찮을 듯...
다소 뜬금없지만, 이벤트 시스템의 일부이기도 하고, 유용한 녀석들이니 언급은 하고 넘어가야 할 것 같다:
- dojo.subscribe(토픽이름, 토픽핸들러함수) : 지정한 토픽이 발생하면 호출할 핸들러함수를 추가한다.
- dojo.publish(토픽이름, 파라메터배열) : 지정한 토픽을 발생시킨다. 그러면, 위의 dojo.subscribe()를 통해 등록한 핸들러 함수들이 모두 호출된다.
다음은 dojo의 객체 시스템에 대해서 알아보기로 하고...
오늘은... 이만...
정말... 덥다...
'hacking > web' 카테고리의 다른 글
dojo by example(7) - object system (0) | 2008.08.20 |
---|---|
씽크프리 노트를 원격 블로깅 도구로 활용하기 (2) | 2008.08.13 |
전문가다운 Ajax 응용 프로그램 개발, Part 1: Prototype 자바스크립트 라이브러리와 script.aculo.us 사용하기 (0) | 2008.08.06 |
dojo by example(5) - 애니메이션/효과 (0) | 2008.08.02 |
Ajax 성능 도구 (0) | 2008.07.30 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- 노래
- ***1/2
- Java
- 땅끝마을
- JavaScript
- 영화
- ****
- web
- HTML5
- Prototype
- 자바스크립트
- **
- CSS
- ***
- Eclipse
- webapp
- 자전거
- 장필순
- nodejs
- docker
- maven
- jQuery
- Dojo
- 여행
- 독후감
- DeveloperWorks
- 책
- Ajax
- 해남
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함