hacking/web2011/04/08 13:20
크리에이티브 커먼즈 라이선스
Creative Commons License

xui.js 초간단 리뷰


요약

xui.js는 모바일 html5 웹앱에 특화된 초경량 자바스크립트 라이브러리

특징

  • 초경량(9.4k) - jquery 최소 29k, dojo 최소 31k, jQueryMobile 최소 135k, Sencha Touch 최소 524k, …
  • 단순 명쾌하고 익숙한(jQuery 스타일의 메소드 체이닝) 문법
  • 모바일에 최적화(webkit, ie mobile, blackberry)
  • 제약없는 오픈소스 라이센스(MIT; Sencha의 듀얼 라이센스 대비 장점)

개발 배경

NitobiPhoneGap 용으로 개발한 자바스크립트 라이브러리.

기능 요약

아래에, xui.js가 제공하는 모든(!) 함수를 간략하게 설명합니다. 개발자 분들의 이해를 돕기 위해 대응하는 jquerydojo의 함수도 같이 소개 했습니다.

기본 함수

  • extend(object)
    • 프로토타입 상속
    • [ jquery.extend(), dojo.extend() ]
  • find(selector, context)
    • css 셀렉터에 부합하는 노드 선택.
    • [ jquery.find(), dojo.query() ]
  • set(array)
    • 명시적으로 노트 선택.
  • reduce(elements, index)
    • 중복 제거
    • [ jquery.unique() ]
  • has(selector)
    • css 셀렉터에 부합 여부 확인
    • [ jquery.has(), dojo.query() ]
  • filter(fn)
    • 노드 필터링(제외).
    • [ jquery.filter(), dojo.filter() ]
  • not(selector)
    • css 셀렉터에 부합하지 않는지 확인.
    • [ jquery와 dojo의 not() css selector ]
  • each(fn)
    • 노드 순회
    • [ jquery.each(), dojo.forEach() ]

DOM 조작 함수

  • html(location, html)
    • HTML 컨텐츠 조작.
    • location: inner,outer,top,bottom,remove,before,after 중의 하나(생략가능; 생략하면 inner). 동일한 이름을 가진 단축함수(inner(html) 등) 사용 가능.
    • [ jquery.html(), dojo.place() ]
  • attr(attribute, value):
    • HTML 속성 조작.
    • value를 생략하면 get.
    • [ jquery.attr(), dojo.attr() ]

이벤트 함수

  • on(type, fn)
    • 이벤트 핸들러 등록.
    • type: click, load, touchstart, touchmove, touchend, touchcancel, gesturestart, gesturechange, gestureend, orientationchange 등. 동일한 이름을 가진 단축함수(예: click() 등) 사용 가능.
    • [ jquery.bind(), dojo.connect() ]
  • un(type, fn)
    • 이벤트 핸들러 등록 해제.
    • fn을 생략하면 해당 이벤트에 등록된 모든 이벤트 핸들러 등록 해제.
    • [ jquery.unbind(), dojo.disconnect() ]
  • fire(type, data)
    • 가상의 이벤트 발생.
    • data: 이벤트 핸들러로 전달되는 event 객체의 data 속성으로 전달(생략 가능).
    • [ jquery.trigger() ]

화면 효과 함수

  • tween(properties, callback)
    • css 속성 인비트윈(inbetween) 에니메이션.
    • properties: 에니메이트할 css 속성-값 pairs과 duration, after, easing 등의 추가 속성들 또는 속성들의 배열.
    • [ jquery.animateProperty(),  dojo.animateProperty() 등 ]

CSS 스타일 함수

  • setStyle(property, value)
    • css 속성 설정.
    • [ jquery.css(), dojo.style() ]
  • getStyle(property, callback)
    • css (계산된)속성 얻기.
    • [ jquery.css(), dojo.style() ]
  • addClass(className)
    • css 클래스 추가.
    • [ jquery.addClass(), dojo.addClass() ]
  • hasClass(className)
    • css 클래스 확인.
    • [ 참고: jquery.hasClass(), dojo.hasClass() ]
  • removeClass(className)
    • css 클래스 제거.
    • [ jquery.removeClass(), dojo.removeClass() ]
  • css(properties)
    • css 속성 일괄 설정.
    • [ jquery.css(), dojo.style() ]

XHR(AJAX) 함수

  • xhr(loation, url, options|fn)
    • AJAX 요청.
    • location: 결과(responseText)를 반영할 노드(생략 가능).
    • options: method, async, data, callback 등의 추가 속성 지정(생략 하거나 callback 함수만 지정 가능).
    • [ jquery.ajax(), ajax.load(), ajax.get(), ajax.post(), dojo.xhr(), dojo.xhrGet(), dojo.xhrPost()  등 ]

결론

xui.js는 jquery나 dojo 등의 기존 자바스크립트 라이브러리에서 널리 사용되지 않는 기능들과 다양한 데스크탑용 브라우져 지원을 위한 부가적인 코드를 제거하고, 자주 사용되는 함수들과 모바일 환경에서 꼭 필요한 브라우져만 지원하도록 최적화된 자바스크립트 라이브러리 입니다. 장단점을 요약하면 다음과 같습니다:
  • PROS: 크기, 성능, 구성, 소스 코드 품질
  • CONS: UI 툴킷 부재. 데스크탑 브라우져 호환성 부재. 문서 / 사용자 커뮤니티  부재.

직접 UI 툴킷을 만들 게 아니라면, 별도의 UI 툴킷을 사용해야 하므로 작은 크기로 인한 장점이 오히려 단점이 됩니다. JQueryMobile을 쓰려면 결국 jQuery가, Sench Touch를 쓰려면 결국 ExtJS가, Dijit(Dojo Widget)을 쓰려면 결국 dojo가 필요하게 되는데, 말 그대로 배보다 배꼽이 더 큰 상황이 됩니다. 또한, 데스크탑 브라우져 호환성이 부족하므로 xui.js는 모바일 웹에만 적용하고, 데스크탑 웹을 위해 별도의 자바스크립트 라이브러리를 사용해야 하므로 2중의 학습/개발이 필요하므로 장점보다는 단점이 커 보입니다.

여러 측면을 고려할 때, 새로운 모바일 웹 UI 툴킷을 자체 개발하거나, 새로운 범용 자바스크립트 라이브러리를 자체 개발한다면 좋은 기반(혹은 참고)가 될 수 있겠지만, 기존의 범용 자바스크립트 라이브러리(jquery, prototype, dojo 등...)의 대체품으로는 부적합 -_-;

저작자 표시 동일 조건 변경 허락
Posted by iolo
hacking/web2010/11/16 12:55
크리에이티브 커먼즈 라이선스
Creative Commons License
사무실에 앉아서 이짓꺼리(?) 하고 있다.

이런 쓰잘데기 없는 동영상을 굳이 만들어 올리는 이유는 "웹 앱"(WebApp; HTML5App)이 그렇게 거창한 것도 아니고, 어려운 것도 아니고, 멀리 있는 남의 나라 이야기도 아니라는 것을 보여주기 위해서다.
PhoneGap, Titanium, QuickConnect 같은 거창한(?) 제품을 동원하지 않더라도 JQueryMobile, Jo, Wink, Sencha Touch 같은 UI 툴킷과 HTML5 canvas 태그 그리고 HTML5 JS API들(WebStorage, WebSQLDatabase, WebWorker, ...), 그리고 W3C의 DAP(Geolocation, ...)를 사용하면 웬만한 앱은 만들 수 있다.

(저번에 XCode로 했던 짓이랑 비슷해서 이번에는 시간이 많이 안걸렸다능 -.-V)



동영상 간의 의존성을 제거(?!)하기 위해 html과 js를 직접 입력했지만, 저번에 아이폰 앱 만들때 썼던 파일을 그대로 써도 된다. 당연한 얘기~

마찬가지로, 예제 소스는 github에 올려두었다.

담(이건 정말 술 이름인데...)에는 좀 더 그럴싸한 앱을 만들어보자. 뭘 만들까? 흠...

저작자 표시 동일 조건 변경 허락
Posted by iolo
hacking/web2009/12/10 17:15
크리에이티브 커먼즈 라이선스
Creative Commons License
원래 발표 자료는 총 15장이 었는데, 예제 코드와 설명이 필요한 것은 이번으로 마무리 하려고 한다.

implicit type conversion

자바스크립트는 약한 타입(weak typing) 이므로, 묵시적인 형변환(implicit type conversion)이 빈번하게 이루어진다. 이로 인한 부작용을 간과하면 찾기 어려운 버그를 만들 수 있다.

간단한 예를 통해 알아보자:
function test(foo) {
  alert(typeof(foo));
  alert(foo);
  if (foo) { alert('foo'); }
  if (foo == null) { alert('foo == null'); }
  if (foo === null) { alert('foo === null'); }
}

이 함수를 여러가지 파라메터를 주면서 호출해보자.
test();
test(null);
test('hello');
test('');
test(true);
test(false);
test(1);
test(1/0);
test(0/0);

특이한 것 몇가지만 얘기하면:
  • underfined는 == null 이지만 === null 은 아니다.
  • ''는 false다! (C에서는 !=0 이면 모두 true라는 사실을 기억하라)
  • 1/0(불능)은 true지만, 0/0(부정)은 false다!

묵시적 형변환과 관련된 또 다른 예를 살펴보자:
function test(foo) {
  alert(typeof(foo));
  alert(foo);
  if (foo) { alert('foo'); }
  if (!foo) { alert('!foo'); }
  if (!!foo) { alert('!!foo'); }
}

파라메터가 명확한 불린 값이라면(true/false) 아무런 문제가 없지만, 그렇지 못하면 예상치 못한 상황에 직면하게 된다:
test(true);
test(false);
test('true');
test('false');

특이한 것은:
  • !!'false'는 false가 아니라 true다.

weak typing은 아주 편리한 언어적 특성이지만, 잘못쓰면 - 특히 strong typing(C, 자바 등의 대부분의 주류 언어)에 익숙한 개발자들에게 - 치명적인 독이 될 수 있다. underfined, null, NaN 그리고 ""(빈문자열) 간의 차이는 상당히 오묘하므로, 가장 확실한 방법은 확신이 없다면 명시적인 형변환을 수행하는 것이다.

nested block scope

function test() {
  var foo = -1;
  for (var foo = 0; foo < 10; foo++) { … }
  alert(foo);
}

위의 코드에서 두번째 var 선언문은 아무 효과가 없다. 따라서, -1이 아니라 10이 출력된다. 별것 아닌것 처럼 보이지만, 문제가 되면 굉장히 찾기 어려운 버그다. jslint를 사용하면 경고를 해주는 데, 가장 확실한 방법은 모든 변수 선언을 함수 앞에 모아두는 것이다(예전 C 스타일).
 
function overloading

function test(foo) {
  alert('one arg');
}
function test(foo, bar) {
  alert('two args');
}
function test() {
  for (var i = 0; i < arguments.length; i++) {
    alert(arguments[i]);
  }
}

위의 코드에서 앞에 두개의 함수 정의는 무시되고, 마지막의 세번째 함수 정의만 유효하다. 자바스크립트에서는 arguments를 사용하여 가변 파라메터를 처리할 수 있다. 그러나, 더 좋은 방법은 이름있는 파라메터를 사용하는 것이다. 즉, 객체 하나에 파라메터의 이름과 값을 함께 전달 하는 것인데, 요즘 많이 쓰이는 대부분의 자바스크립트 라이브러리들이 모두 이 방식을 선호한다.

"string" is not array-of-chars

var str = "hello";
alert(str.charAt(2));
alert(str[2]);

위의 코드에서 앞의 alert은 출력되지만, 뒤의 alert은 에러다. 잘된다고? IE에서는 해보시길...
자바 개발자들에겐 익숙할텐데, C/C++ 개발자들은 좀 귀찮을 듯... ^^;

비슷한 예로, NodeList(예: document.getElementsByName() 등의 리턴 형식)도 배열이 아니다.

missing "radix" for  parseInt()

parseInt('1234');
parseInt('01234');
parseInt('0x1234');
parseInt('1234', 10); 
parseInt('1234', 8);
parseInt('1234', 16);

뭐가 이상하냐고? 자바에서 똑같은 짓을 해보자. -.-;;;; 자바에선 Integer.parseInt()에 radix를 지정하지 않으면 10을 지정한 것으로 처리하지만, 자바스크립트에선 알아서 하라는 뜻으로 해석한다.

var sum = parseInt(num1.value) + parseInt(num2.value);
alert(sum);

위의 코드는 의도했던 안했던, 8진수와 16진수 계산기 기능도 갖고 있다. ^^; 이런 사소한 문제가 찾아내기 힘든 버그를 만든다. jslint를 사용하면 경고를 해주는데, 가장 확실한 방법은 parseInt()를 호출할 때 무조건 두번째 파라메터(radix)를 지정하는 것이다. 

이것으로 JavaScript Common Mistakes 시리즈도 끝~
그 시작은 창대하였으나 끝은 미미하리라...=3=3=333

아.. 쪽팔려...

저작자 표시 동일 조건 변경 허락
Posted by iolo
hacking/web2009/12/09 19:55
크리에이티브 커먼즈 라이선스
Creative Commons License
자바스크립트로 심각한 코딩을 하기 시작하던 초기에 했던 삽질이다. 그 전까진 아예 "this"라는 키워드를 쓸 일 자체가 없었다.

가장 간단한 예제를 보자:
function test(name, button) {
this.name = name;
button.onclick = function(event) {
alert('hello, ' + this.name);
};
}
문제는, 이 코드에서 아래에 있는(4줄) "this"가 위에 있는(줄2) 그 "this"가 아니라는 건데...

그럼 어떻게 해야하나? 여러가지 방법이 있겠지만, 가장 일반 적인 방법은 이렇게 하는 거다:
function test(name, button) {
this.name = name;
var self = this;
button.onclick = function(event) {
alert('hello, ' + self.name);
};
}
변수 이름은 self가 아니어도 상관없지만, 일반적으로 self, me, this_, _this 등을 많이 쓴다.

이론에 근거한 체계적인 설명은 크록포드옹께서 쓰신 JavaScript: The Good Parts 를 정독하시고...

이것만 기억하자:
자바스크립트의 this는 함수가 "선언된 위치"가 아니라, 함수가 "호출 문맥(invocation context)호출된 위치"에 따라 결정된다.

위의 코드에서, 사용자가 버튼을 누르면 button.onclick에 연결된 콜백 함수를 호출하는데, 그 시점의 this는 함수가 선언된 위치인 test 객체가 아니라, 콜백 함수를 호출하는 "버튼"(DOM 노드)이다. 그래서 엉뚱한 값(버튼 태그의 name 속성 값)이 출력되는 것이다.

더 헷갈리다고...? Orz

대부분의 this와 관련된 문제는 위에서 설명한 꼼수와 자바스크립트의 Function.prototype.apply()Function.prorotype.call() 를 통해 해결할 수 있다. prototype.js 의 Function.bind() 와 dojo 의 dojo.hitch() 도 결국은 같은 일을 한다(그래서 jQuery에는 없다).

흠냐... 아직 많이 남았는데... 벌써... 귀차니즘 발동... -,.-;;;

저작자 표시 동일 조건 변경 허락
Posted by iolo
hacking/web2009/12/08 17:21
크리에이티브 커먼즈 라이선스
Creative Commons License
내 스스로와의 약속(하루에 한개씩 블로그를 쓰겠다는)을 지키면서, 또 다른 약속(지난 번 dW Live!의 페차쿠차 발표에 대한 보충 수업을 하겠다는)을 지키기 위해 여러 번에 나눠 쓰기로 했다 :p

천덕꾸러기 취급 받던 자바스크립트가 다시 각광을 받게된 것은 웹2.0 열풍에 실려 날아온 AJAX 때문이다. AJAX의 A가 Asynchronous라는 것은 자바스크립트 개발자라면 누구나 아는 사실임에 종종 이를 망각하는 경우가 있다.

가장 쉬운 예를 보자:
function get_result() {
  var result1, result2;
  $.ajax({ ..., success: function(data) { result1 = data; });
  $.ajax({ ..., success: function(data) { result2 = data; });
  return result1 + result2;
}

이게 뭐가 문제냐~고 하시면 대략 난감~ 정말 곤란~하시다.

설마 저렇게야 하겠어라고 생각하신다면, 좀 더 그럴듯한 예를 들어보자:
function get_image_size(image_src) {
  var img = new Image();
  img.src = image_src;
  return { w: img.width, h: img.height; };
}

이미지를 자바스크립트로 동적으로 이미지를 로딩하고 크기를 구해서 어떤 짓을 하려나 본데...
뭐가 문제냐고? 없으면 말고~=3=3=33

좀 더 고급스런(?) 예제로 마무리하자:
<script src="http://www.google.com/jsapi"></script>
<script>
google.load("jquery", "1");
$(document).ready(function() { ... });
</script>

좀 더 나은(정답은 없다) 방법은... 스스로 생각해 보시길...=3=3=33

i'll be back~

i'll be back~



저작자 표시 동일 조건 변경 허락
Posted by iolo