티스토리 툴바


블로그 이미지
카라크라스

Leon.Kim의 공부하는 블로그입니다. mail - kalaklas@gmail.com twitter - @kalaklas

Rss feed Tistory
Web/Javascript 2011/11/05 21:57

html5 data-attribute javascript로 사용하기

Using data- attributes with JavaScript
Now that we understand what custom data- attributes are and when we can use them, we should probably take a look at how we can interact with them using JavaScript.

If we wanted to retrieve or update these attributes using existing, native JavaScript, then we can do so using the getAttribute and setAttribute methods as shown below:

저작자 표시 비영리 변경 금지
Web/Javascript 2011/07/26 14:15

CommonJS - not just for browsers any more!

CommonJS - not just for browsers any more!



정말 신선하고, 충격적이며 멋있는 주제가 아닐수 없다 +_+a
미루고 미루다가 드디어 한번 구경해 보게 되었다
http://www.commonjs.org/

그동안 javascript는 브라우저에서만 수행되는 인터프리터 언어로서 취급 되어져 왔다.
나도 그리 생각했었다.
하지만 javascript의 영역이 계속 넓혀지고 있다.

The official JavaScript specification defines APIs for some objects that are useful for building browser

javascript는 이제 브라우저를 뛰쳐 나가고 싶어졌고, 많은 개발자들이 이 꿈을 지원해주고있다.
향후 아래와 같은 환경에서도 이제 js는 큰 역할을 짊어 질수 있을것 같다.
• Server-side JavaScript applications 
• Command line tools 
• Desktop GUI-based applications 
• Hybrid applications 

The CommonJS API will fill that gap by defining APIs that handle many common application needs, ultimately providing a standard library as rich as those of Python, Ruby and Java.

CommonJS에서 제안하고 있는 표준스팩들은 아래와 같다.
http://www.commonjs.org/specs/
•Modules
•Binary strings and buffers
•Charset encodings
•Binary, buffered, and textual input and output (io) streams
•System process arguments, environment, and streams
•File system interface
•Socket streams
•Unit test assertions, running, and reporting
•Web server gateway interface, JSGI
•Local and remote packages and package management

위 제안들을 모두 구현한 구현체가 0.x대 버전을 넘어 1.x대로 진화하는 이후 부터 어떤 일들이 벌어질지 정말 기대된다.
이미 CommonJS에서 제안한 표준에 따라 구현된 구현체들이 상당하다.
아래 주소에서 확인 가능하다.
http://www.commonjs.org/impl/

Node.js 역시 CommonJS의 제안한 표준을 따라 CommonJS에서 정의한 모듈들을 일부 구현하였다.
현재 Node.js는 아래와 같은 상태로서 
v0.4.10 (stable) 
v0.5.2 (unstable) 
http://nodejs.org/#download
0.4 ~0.5 대 버전임에도 불구하고, 벌써부터 Node.js등을 열심히 지지고 볶고 있는 사람들이 많아진것을 구글링을 통해 쉽게 알수 있다.

간단하게 CommonJS에서 제안하고 있는 JS모듈을 Node.js에서 어떻게 사용하는지 모양을 살펴보자.
흔히 FF에 console에서 로그를 찍어보기 위해 console.log(), console.dir() 메소드를 사용하는데, 
http://wiki.commonjs.org/wiki/Console에 해당 모듈도 논의의 대상으로서 리스트에 올라 있다.
현재 Console의 논의 상태와 제안 내용을 살펴 볼수 있다.
11년 7월 현재 아직 PROPOSED, DISCUSSED, SOME IMPLEMENTATIONS 상태임을 알수 있다.

Node.js에서는 이미 이 제안을 참고하여 구현되어있고, 해당 모듈의 사용이 가능하다.
Node.js에서 100%는 아니지만 몇몇 기능을 구현하였고 아래와 같은 형태로 사용이 가능하다.
var maLog = require("console");
maLog.log("Hello world~!!");
-출력결과 당연히 Hello world~!! 라는 주어진 문자열을 출력
>Hello world~!!

maLog.dir(maLog);
-출력결과 당연히 maLog 객체에 assign된 console 모듈 내용을 출력한다. 
- 현재 Node.js에서는 Console스펙의 16가지 기능중 9가지 기능을 구현 제공하고 있음을 알수 있다.
>
{ log: [Function],  
   info: [Function],  
   warn: [Function],  
   error: [Function],  
   dir: [Function],  
   time: [Function],  
   timeEnd: [Function],  
   trace: [Function],  
   assert: [Function] 
}
슬슬 Node.js를 열심히 만져 보아야겠다.
저작자 표시 비영리 변경 금지
Web/Javascript 2010/11/02 02:04

jQuery 압축

웹어플리케이션 수행시 js,css등의 리소스들이 서버로부터 클라이언트로 로드된다.
js, css전송 파일 크기가 작다, 전송 갯수 적다 == 서버 부하를 줄여준다(트래픽을 줄여준다) == 웹어플리케이션 성능이 좋아진다

따라서 js 와 css는 압축이라는 빌드 과정을 이용하여 여러개로 구성된 모듈 js, css 파일들을 하나의 파일로 구성하는
과정은 웹어플리케이션 성능을 높이는데, 큰 역할을 한다.

아래와 같은 압축 툴들이 존재한다.
  • YUI Compressor (from Yahoo)
  • JSMin (by Douglas Crockford)
  • ShrinkSafe  (from Dojo library)
  • Packer (by Dean Edwards)
     
    보통 YUI Compressor  추천된다 - Java 기반
    다양하게 이용이 가능하다
     
    1. 웹사이트 툴을 이용한 압축 
    > 아래 웹사이트로 간단하게 테스트가 가능하다.
    http://yui.2clics.net/

  • 2. Command Option 이용한 실행 
    > java -jar yuicompressor-x.y.z.jar myfile.js -o myfile-min.js //빌드 시스템에 결합 가능
    (내가 속한 개발팀의 경우 dojo에서 제공하는 shrinksafe를 빌드 시스템과 연동 시켜 모든 js 모듈 압축 과정을 자동화 하였다.)
  •  
  • Compressor 하는일
    공백(들여쓰기, 공백라인등), 주석제거, Obfuscating, 다수의 js 소스 파일 결합등을 대신하여 준다.
     
    주의사항 >> 예를 들어 아래와 같은 주의 사항이 필요하다.
  •  dependency 고려하여 파일 결합 순서에 유의
    소스 " ; " 무조건 붙여줘야한다. 
    var myValue = a+ ++a;  ==> var myValue = a+(++a);
     
    http://www.jslint.com/lint.html 에 크록포드님께서 언급한대로만 잘 짜면 문제없을것이다 ( 고로 >> JSLint 이용하여 JS소스 검증  압축하자.)

  • 역시나 어설픈 나의 포스팅 ㅋㅋㅋ
     
JavaScript, jQuery
Web/Javascript 2010/10/21 11:43

jQuery widget 에 관하여.


jQuery ui plugin들은 모두 jquery.ui.widget 즉 widget factory를 이용하여 개발되었다.


widget factory는 custom widget class를 만들수 있는 factory method를 제공한다.

jquery.ui.widget.js을 이용하여 custom ui widget class를 만들어 보고, 적용해보자.


아주 간단히 말해 jquery.widget 을 이용하여, 내 위젯을 만드는 방법은 
$.widget("ui.mywidget", {});
로 단축된다. 

widget factory
기본 메소드
  • destroy(): Removes the instance from the encapsulated DOM element, which was stored on instance creation
  • option(String key[, String value]): Gets or sets an option for this instance
  • enable(): Set disabled option to false, it's up to the instance to respect the option
  • disable(): Set disabled option to true, it's up to the instance to respect the option
기본 프로퍼티
  • options: The options for this widget instance, a mix of defaults with settings provided by the user
  • element: A jQuery object always containing a single DOMElement, which can be accessed with this.element[0].

내 위젯 내부에서 위의 메소드와 프로퍼티의 사용이 언제든 가능하여, override 가능하다.
default method를 상속(?실행? 자바로 치면 super클래스의 메소드를 수행고자 할때 . .)
$.Widget.prototype.methodToOverride.apply(this, arguments); // 아래 소스를 보면 widget protype의 destroy를 수행하는 모습을 볼수 있다.


* 간단하게 mybutton이라는 widget을 만들어 보았다.

widget factory은 자동으로 _create -> _init 순으로 메소드를 수행하는 cycle을 가지고 있다.
widget을 위한 custom method은 자유롭게 추가가 가능하다.

간단하게 mybutton이라는 위젯을 만들어 보았다.
편의상 css style등을 모두 내부에 포함하였다.

더보기



jquery.widget이 제공하는 widget factory를 이용하여 widget을 정의 할 경우 내부적으로

$.Widget.prototype을 override하여, 위젯이 정의된다.

$.Widget.prototype은 다음과 같은 구성으로 이루어져 있다.
소스코드에서 확인 할 수 있듯 _createWidget 메소드가 widget의 life cycle을 정의하고 있다.
_create() -> _init()
_create : 스타일, Node 생성, Event 정의등 widget을 정의하는 행위를 수행하는 메소드로서 오
버라이드 하자.
_init() : 위젯의 초기 상태를 지정하는 행위를 수행하는 메소드로서 오버라이드 하자.

상위 ($.Widget.prototype) 상속(?) 객체의 메소드 수행시
$.Widget.prototype.methodToOverride.apply(this, arguments); 와 같은 방식으로
apply 수행하면 된다.

widget() : 각 widget들은 모두 각각의 this.element 를 가지고 있는데, 이 element Node를
유용하게 return 받아 사용할 수 있다.

destroy : 이 메소드는 Widget을 제거 할 때(?) 수행할 메소드로서, 메모리 반납 (에를
들어 bind된 이벤트의 해지) 행위를 수행하면 된다.
==> $.Widget.prototype.destroy.apply(this, arguments); 수행

더보기






자신 만의 ui widget 을 jQuery.ui.widget이 제공하는 widget팩토리 메소드를 이용하여 만들어보자.

(아 항상 이렇게 어설픈 마무리 ㅠㅠ)


Web/Javascript 2010/10/20 10:45

jQuery 간단 스터디 계속 - Class 지향 플러그인 개발등

4. jQuery를 이용한 객체지향 프로그래밍(?)
jQuery Klass 라는 녀석을 써서 class를 구성할 수 있다.
http://code.google.com/p/jquery-klass/ 에 MIT License로 프로젝트가 공개되어 있으나, 소스의 다운이 불가능하다;; 이건 대체 왜 이런 상태로 방치하고 있는건지 모르겠따;;;

http://github.com/danwrong/low-pro-for-jquery 로 이동하여 low-pro-for-jquery 플러그인
을 프로젝트에 포함 시킨다.

아래와 같이 NameSpace를 오염 시키지 않는 선에서 com.custom 페키지에 Animal 클래스를 
선언해 보았다.

필드로 name, sound를 갖고 생성자 initialize, setSound, getSound, say 메소드등을 지원하는
아쥬 아쥬 간단한 클래스다.

더보기

//  클래스 필드와 클래스 메소드는 아래와 같이 정의한다.
com.custom.Animal.constant = {};

com.custom.Animal.constant.countA = 10;

com.custom.Animal.constant.countB = 100;

com.custom.Animal.classMethod = function(){

console.log("it's Animal's class Method");

};



* 사용

var maAnimal = new com.custom.Animal("pig");

maAnimal.setSound("꿀꿀");

maAnimal.say();

com.custom.Animal.classMethod();

이렇게 쓰면된다.

아래와 같은 방법으로 SubAnimal 클래스를 Animal클래스를 상속히여 구현이 가능하다.

super클래스 메소드에 접근하는 방법은 좀 더 조사해보고, 추가해야겠다.

com.custom.SubAnimal = $.klass(com.custom.Animal, {

initialize: function(sound){

console.log("SubAnimal initialize");

}

});

Web/Javascript 2010/10/01 00:06

jQuery에 대한 간단한 스터디 정리


dojo이외 다른 javascript toolkit은 어떻게 구현 동작하는지 궁금해서
jQuery Cookbook을 일주일간 읽어보고 아래와 같은 목차로 나름의 정리를 해보았다.

목차
1. jQuery를 들어가며

2. jQuery기초
a. 돔탐색과 유틸들
b. jQuery Ajax
c. jQuery 이벤트

3. jQuery 플러그인
a. jQuery 외부 플러그인을 가져와서 써보기
b. jQuery Custom Plugin 개발해서 적용해보기
c. 외부 플러그인 가져오고, Custom 플러그인 개발할때 고려해야할 사항을 무엇이 있을까?

4. jQuery를 이용한 객체지향 프로그래밍

5. jQuery 최적화
a. 내가 만든 플러그인 js를 최적화 시켜보자.

6. jQuery 는 HTML5를 Support할까?












1. jQuery를 들어가며
왜 jQuery?
오픈소스로서 무료다.
라이브러리가 매우작다  114kb 이며, minify된 녀석은 18kb
수많은 커뮤니티
크로스브라우징을 내부에서 지원하여, 크로스브라우징에 관한 고민이 덜하다 (대부분의 javascript 라이브러리들이 그렇듯 . . .)
플러그인자료실이 광범위하며, 꾸준히 발전하고 있다
API가 완전하게 문서화 되어있다
다른 javascript 라이브러리들과 충돌을 방지해 주는 방법을 제공한다
개발자 뿐만 아니라 디자이너에게 있어서도 무척 친화적인 라이브러리이다

Write less, do more - 적게 작성하고, 보다 많이 한다.
      요소를 찾아 jQuery 메서드를 사용하여 작업을 수행한다
         DOM요소를 찾아서 작업을 수행한다
      요소 집합에 대해 여러 jQuery 메서드를 체인으로 연결한다
         jQuery를 이용하여 선택한 DOM요소에 jQuery 메서드를 체이닝하여 사용한다
         jQuery('#id').hide().text('identity').addClass('thisStyle').show();
         이는 내부적으로 체이닝을 지원하는 방식(래핑된 객체를 무조건 반환도록하는 방식)으로 구
          되어 있기에 가능하다. (나중에 우리가 메서드를 확장하거나 한다면, 당연히 래핑객체를 무
         조건 반환도록 구현 해줘야 체이닝이 끈어지지 않겠지)
      jQuery래퍼와 암시적인 반복을 사용한다
         jQuery를 이용하여 DOM을 탐색하면, 해당 DOM은 jQuery 기능이 래핑된다.
         var aNode = jQuery('#rokim'); // aNode jQuery가 래핑된 객체를 반환 받을 것이다.

jQuery API 구성
http://visualjquery.com/ 가 정말 쓸만한듯. 최신 jquery(지금은 1.4)의 API는 아니지만 . .
http://api.jquery.com/ 정식 API 온라인 문서의 URL이다.

JAVA 못지 않게 매우 잘 정리되어있다.

  • All
  • +Ajax
  •  Attributes
  •  Core
  •  CSS
  •  Data
  •  Dimensions
  • +Effects
  • +Events
  •  Forms
  • +Manipulation
  • +Miscellaneous
  •  Offset
  •  Plugin Authoring
  • +Properties
  • +Selectors
  • +Traversing
  •  Utilities
  • +Version
  •         


    2. jQuery기초
    a. 돔탐색과 유틸들

    돔탐색.
    http://api.jquery.com/category/traversing/ 에는 다양한 Traversing 메소드들이 잘 설명 되어 있으니 살펴 봐가며, 활용해보자. 아래는 간단한 몇가지 테스트 코드
    셀렉터와 jquery함수를 사용하여 DOM 요소 탐색하기
    jQuery는 pure-JavaScript CSS selector engine인 Sizzle 라이브러리를 include하여 좀더 강력한 DOM탐색을 지원한다 (자세한 정보 : sizzlejs.com)
    jQuery() 또는 $()
    var aNodes = jQuery('a'); //document내에 모든 <a> 요소를 선택한다
    var customNode = jQuery('#custom'); //document내에 id=custom인 요소를 선택한다
    var customNodes = jQuery('.classA'); //classA style class명을 적용받고 있는 요소를 선택한다.
    var customNodes = jQuery('#a, #b, div, ') ; //id를 a,b갖는 요소와 선택한다.
    var customNodes = jQuery('span', 'div'); // div 하위의 span 요소를 선택한다. 
     var customNodes  = jQuery('div span'); // 위와 동일하게 div하위 span요소를 선택한다. css셀렉터 표현식을 사용하니 더 간편하다.

    컨텍스트 기반 DOM 탐색 
        console.log("====== context based DOM Search test ");
        var tempNode = jQuery('#a');
        console.log(tempNode.text());
        console.log(tempNode.next().text());
        console.log(tempNode.nextAll().text());
        console.log(tempNode.parent().children().text());

    DOM을 생성하여 특정 Node에 Append하기
    jQuery('<div><span>Sweet candy</span></div>').find('span').addClass('classB').end().appendTo('#away');
    //DOM요소를 생성해서 span 요소에 classB css 스타일을 적용한뒤 away id를 가진 노드에 append한다.
    appendTo 이외에도 append(),
    prepend(), prependTo(),
    insertAfter(), insertBefore(),
    after(). before(), 등등 많다.

    DOM요소 제거
    jQuery('a').remove(); //a태그 요소 제거
    jQuery('a').remove('.classA') //a태그 classA클래스 적용된 녀석 제거

    DOM요소 교체
    var aNode = jQuery('#a'); var bNode = jQuery('#b');
    jQuery(aNode).replaceWith(bNode); //aNode를 bNode로 replace한다

    선택한 DOM 노드 선택 요소 집합을 루프 돌며 처리하기
        var awayNodes = jQuery('#away > span'); //away id가진 녀석 하위 span 요소들 선택
        jQuery.each(awayNodes, function(i){
    if(i%2 == 0){
          $(this).addClass('classA'); //i가 짝수면 이 요소에  classA 적용
    else{
          $(this).addClass('classB'); //i가 찍수면 이 요소에 classB 적용
    }
        });



    알아두어면 좋은 몇가지 유틸들
    jQuery.support  : console.dir(jQuery.support); object를 살펴보면 다양한 어트리뷰트들을 확인 할 수 있는데, 이는 브라우저의 기능을 탐지해서, 해당 어트리뷰트에 불린값을 가지고 있게된다.
     뭐 예를 들면 jQuery.support.tbody 의 경우 브라우저가 <tbody>요소가 없이도 table요소를 허락하는지 여부를 불린값으로 알려주는데, FF에서 당연히 true로 세팅되어 있다.
    기회가 되면 살펴 보도록하쟝

    jQuery.each() : 배열과 개체를 루프 돌며 처리

    jQuery.grep() : 배열에서 요소를 필터링 제거 할때

    jQuery.merge() : 배열 merging

    jQuery.extend() : 개체 확장




    b. jQuery Ajax

     jQuery의 ajax설계 구조에 있어 jquery.ajax() 메소드는 핵심이다.
    녀석은 모든 브라우저에서의 ajax call 기반을 제공한다.
    옵션 프로퍼티
    type : GET/POST
    url : 요청 url
    dataType : 서버로부터 반환될 데이터 타입에 대한 정의
    error : 에러 콜백
    success : 성공 콜백


    c. jQuery 이벤트 
    jQuery 이벤트 시스템은 는 이벤트 지향 프로그래밍을 지원하기에 bind  trigger될 수 있는 사용자 정의 이벤트를 만드는것이 가능하다.
    jQuery(listener).eventName(handlerFunction);


    예> 
    //myButton id를 가진 node를 클릭했을때, 해당 function 수행
    jQuery('#myButton').click(function(e){  
    console.log("Custom Event ~!");
    });

    //myButton id를 가진 node를 클릭했을때, 해당 function 수행
    jQuery('#myButton').bind('click', function(e){
    console.log("Custom Event ~!");
    });

    //myButton id를 사진 node를 click 또는 keydown했을때 해당 function 수행
    jQuery('#myButton').bind('click keydown', function(e){
    console.log("Custom Event ~!");
    });



    //이벤트에 정의해둔 function myEventHandler을 바인드
    function myEventHandler(e){
    if(!e.data){
    console.log("it's my event handler : nothing");
    return;
    }else{
    var userInfo = e.data;
    console.log('name : ' + e.data.name + userInfo.address + userInfo.age);
    return;
    }

    }

    jQuery('#myButton').click(myEventHandler).keydown(myEventHandler);

    jQuery('#myButton').bind('click keydown', muEventHandler);



    //데이타와 함께 이벤트 사용
    jQuery('#myButton').bind('click', 
    {name:'raeok', 
    address:'Seoul at Korea', 
    age:'28'}, 
    myEventHandler);




    //이벤트 처리기 전체를 제거하기
    특정 DOM요소에 바인드했떤 모든 이벤트 바인딩을 제거 하고 싶을때는 어떻게 해야할까?
    각각의 이벤트 플러그인에 네임스페이슷 줘서 한번에 관리하자~!

    jQuery('myButtonA').bind('click.myEventPlug', function (){
    console.log("event was launched");
    });

    jQuery('myButtonA').bind('click.myEventPlug', function (){
    console.log("event was launched");
    });

    jQuery('myButtonB').bind('click.myEventPlug', function (){

    console.log("event was launched");
    });

    this.unbind('. myEventPlug'); //해당 이벤트 바인드를 제거

    this.trigger('click.myEventPlug'); // 강제 수행


    //간략한 bind // unbind 예
    $(window).ready(function(){
    jQuery.fn.myPlugin = function(){
    console.log("myPlugin");
    var clickEvent = function(e){
    console.log('click');
    };
    var mousedownEvent = function(e){
    console.log('mousedown');
    }
    return this.bind('click.myPlugin', clickEvent).bind('mousedown.myPlugin',mousedownEvent);
    }
    jQuery.fn.dispose = function(){
    console.log("dispose");
    return this.unbind('.myPlugin');
    }
    var ajBtn2 = jQuery('#ajBtn2');
    ajBtn2.myPlugin();
    ajBtn2.trigger('click!');
    jQuery.leon = function(obj, name){
    console.log('unbind');
    obj.unbind(name);
    }
    jQuery.leon(ajBtn2, '.myPlugin');
    });
    })(jQuery);


    3. jQuery 플러그인
     jQuery는 메소드와 함수를 플러그인으로 넣을수 있는 방법을 제공한다.
    다운로드해서 사용하는 모든 플러그인들은 jQuery 플러그인 구조를 이용해 만들어져 있다.

    * 플러그인 구성시 주의사항
    파일명을 jquery.[플러그인명].js 로 짓도록 합니다. 예 : jquery.debug.js
    모든 새로운 메소드는 jQuery.fn 개체에 종속되도록 하고, 모든 함수는 jQuery 개체에 종속되게 한다.
    메소드 내에서 'this' 인스턴스는 현재 jQuery 개체를 가리킨다 (메소드 체이닝)

    * public Method 선언은 아래와 같다.
                    jQuery.fn.myPluginMethod = function(){
                        var clickEvent = function(e){
                            alert('click!!!');
                        };
                        
                        var mousedownEvent = function(e){
                            alert('mousedown');
                        }
                        return this.bind('click.myPlugin', clickEvent).bind('mousedown.myPlugin', mousedownEvent);
                    }

    선언한 public method myPluginMethod는 아래와 같이 사용이 가능하다.
    jQuery('#myButton').myPluginMethod ();

    * public 함수(static 함수)의 선언은 아래와 같다.
                    jQuery.myPluginFunction = function(){
                        alert("myPluginFunction");
                    }

    선언한 public function myPluginFunction은 아래와 같이 사용이 가능하다.
    jQuery.myPluginFunction();


    >> 모든 새로운 메소드는 jQuery.fn 개체에 종속되도록 하고, 모든 함수는 jQuery 개체에 종속되게 한다.

    jQuery Method와 Function (메소드와 함수)의 차이는 무엇일까?
    Method는 jQuery개체가 인스턴싱된 이후에 인스턴싱 객체를 통하여서만(selector로 jQuery 래핑된 객체) 사용이 가능하다.


    * 플러그인에 파라미터 전달하기
                    jQuery.fn.myPluginMethod = function(){
    console.dir(arguments);
                        var clickEvent = function(e){
                            alert('click!!!');
                        };
                        
                        var mousedownEvent = function(e){
                            alert('mousedown');
                        }
                        return this.bind('click.myPlugin', clickEvent).bind('mousedown.myPlugin', mousedownEvent);
                    }


                    var ajBtn2 = jQuery('#ajBtn2');
                    ajBtn2.myPluginMethod({name:'leon', age:28}, {a:'A'});

    >> 메소드에 파라미터를 전달할때, 위와같이 arguments로 받아도 되고, 명시적으로 파라미터를 넘겨도 된다.
    만약 내 새로운 플러그인에 이미 존재하는 필드와 존재하지 않는 필드들이 혼재되어 있고, 내가 새로 세팅하고자 하는
    필드가 선택적일때는 어떻게 하면 좋을까?

    extend() 메소드를 이용하여, 전달받은 파라미터를 재정의 하면 된다.+
    jQuery.fn.myPluginMethod = function(options){
    var defaultValue = jQuery.extend({},jQuery.fn.myPluginMethod.defaultValue, options);

    console.dir(defaultValue);
    console.log("name : " + defaultValue.name);
    var clickEvent = function(e){
    alert('click!!!');
    };

    var mousedownEvent = function(e){
    alert('mousedown');
    }
    return this.bind('click.myPlugin', clickEvent).bind('mousedown.myPlugin', mousedownEvent);
    }

    jQuery.fn.myPluginMethod.defaultValue = {
        name: "abc",
        sex: "man"
    };



    a. jQuery 외부 플러그인을 가져와서 써보기
    jQuery UI 플러그인을 이용하여 jQuery.ui.button 버튼을 내 페이지에 붙여보고 동작을 부여해 보자.

    첫번째로 css와 jQuery UI 컴포넌트 셋을 http://jqueryui.com/download 에서 다운 받아 프로젝트에 포함 시킨다.
    http://jqueryui.com/download 에 가보면 jQuery UI를 customize하게 선택하여 다운이 가능하다.
    Download Builder 라는 녀석의 도움을 통해 customize된 jquery ui 을 다운 받자.
    (http://jqueryui.com/docs/Getting_Started 에 Download Builder의 사용법이 자세히 나와있다.)

    두번째로 프로젝트에 포함시킨 ui 컴포넌트 셋을 페이지에 import한다 (빌드전 개발 환경을 위한 세팅을 전제로 하고 있으니 . . . 아래와 같은 구성으로 갈구지는 말자;;ㅋ)
    jquery.ui.button.js는 jquery.ui.core.js와 jquery.ui.widget.js 에 dependency가 걸려 있으므로, 
    아래와 같이 import한다.

      <link href="./lib/jquery/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css"/>
      <script src="./lib/jquery/jquery-1.4.2.js"></script>
      <script src="./lib/jquery/ui/jquery.ui.core.js"></script>
      <script src="./lib/jquery/ui/jquery.ui.widget.js"></script>
      <script src="./lib/jquery/ui/jquery.ui.button.js"></script>

    세번째로 jQuery 셀렉터로 선택한 노드에 버튼 플러그인 메소드를 수행하여 버튼을 인스턴싱한다.
    >> 스크립트
      $(document).ready(function() {
    $("#button").button({label:"myButton"});
      });

    >> html
    <div id="button"></div>



    jQuery UI에서 제공하는 버튼의 tutorial은 http://jqueryui.com/demos/button/ 에서 자세히 확인 가능하다. 








    jQuery
    Web/Javascript 2010/08/06 14:02

    JavaScript Objects Reference


    http://www.w3schools.com/jsref/default.asp

    JavaScript Objects Reference

    The references describe the properties and methods of each object, along with examples.


    Browser Objects Reference

    The references describe the properties and methods of each object, along with examples.


    HTML DOM Objects Reference

    The references describe the properties and methods of each object, along with examples.

    Web/Javascript 2010/07/27 15:07

    html압축을 통한 웹어플리케이션 performance 향상

    <dojo를 이용한 widget 개발 참고
    http://www.ibm.com/developerworks/kr/library/tutorial/wa-dojowidgets/section6.html
    (한참 예전 버전의 dojo를 가지고 설명한 tutorial이라서 약간은 그렇지만 . . . . 충분히 참고는 가능하다)

    html압축을 통한 웹어플리케이션 performance 향상

    performance 향상이라고 하니 너무 거창한것 같다.

    내가 일하는 팀에서는 dojo를 이용하여 widget을 개발하곤 하는데,

    dojo의 콤포넌트는 개발시 직관적으로 디자이너와의 작업을

    원활히 할수 있도록 html템플릿을 기반으로 하여 개발이 가능하다.

    예를 들면 Spinner 패키지에 NumberSpinner 위젯을 개발하는 경우 아래와 같은 폴더 구조가

    이루어진다.




    위와 같은 환경하에서 개발할 경우 개발자와 디자이너간 독립적 분리 개발이 가능하다.
    개발자는 오직 NumberSpinner.js의 개발에만 집중할 수 있다.

    NumberSpinner.js(dijit._Widget, dijit._Templated을 상속 구현한 NumberSpinner클래스)에서 html 템플릿 파일인 NumberSpinner.html을 아래와 같은 코드로 js코드에 임베딩하여 DomNode등에 접근이 가능하다. (템플릿에서도 dojoAttachPoint를 이용하여 js의 메소드들에 접근이 가능하다.)

    templateString: dojo.cache("sample.spinner", "NumberSpinner/NumberSpinner.html")




    아무튼 위와 같은 형태로 위젯 컴포넌트들이 개발되게 되는데, release를 위한 빌드시 위와 같은 폴더 구조는 무의미해 진다.(html 템플릿이 js로 자동으로 귀속? 포함? 된다.)

    이때 NumberSpinner.html 템플릿 파일을 압축하지 않을 경우와 압축을 한후 build를 했을 경우의 layer파일의 용량에 차이가 발생한다. (html파일을 포함 시킬때 필요없는 tag들을 자동으로 생성 시켜주기 때문이다 예를 들면 <t> <r>등과 같은 . . . . 결국 요녀석들을 제거 시키기 위한 html압축인것이다. 한마로 여러 라인의 html 코드 템플릿 파일을 한줄로 압축 시켜버리는거다 )

    웹 어플리케이션에서 js 파일의 용량의 차이는 결국 성능의 차이라는 문제와 동일하다고 볼수 있는데, 용량이 작을 수록 client가 좀 더 빨리 js 파일을 download 받아 action이 가능하기 때문이다. (프로젝트 규모가 그리 크지 않아 widget component가 몇개 되지 않을 경우는 별로 큰 상관이 없을 테지만 . . . 규모가 커질 경우 이 문제는 생각보다 큰 성능상 차이를 발생 시킨다.)

    따라서 개발이 완료된  custom widget component 모듈들을 build하기 직전 temlplate html들
    의 압축 작업을 진행한 후 build를 진행하면, 좀 더 작은 용량의 결과물을 획득 할 수 있겠고,
    원하는 성능 향상의 소기의 목적을 달성할 수 있다(html 압축 뿐만 아니라 신경 써야할 부분이
    상당히 있지만 . . . 목적상 html 압축만을 다룬다. 물론 shrinksafe, yui compressor, closure등
    의 다양한 js압축기를 이용한 js파일의 압축은 논외로 한다. 이들은 html을 압축해 주지는 않는
    다 내가 알기론;;;ㅋ)



    그래서 간단한 html 압축기를 개발했는데, 이게 생각보다 상당한 고려사항들이 존재 하였다.
    틀어 막고 틀어 막아도 여기 저기서 새는 문제들이 한두개가 아니었다.
    모든 html tag들에 대하여 대응하는 삽질과 다양한 예외 사항에 대한 대비는 사실상 불가능에
    가까웠다 . . .

    그런데 google code에 com.googlecode.htmlcompressor.compressor.HtmlCompressor
    HtmlCompressor이라는 아주 좋은 프로젝트가 진행되고 있었다. 내가 만든 압축기와 이름마저 동일했다 ㅋㅋㅋ

    HtmlCompressor : http://code.google.com/p/htmlcompressor/

    아래와 같은 카테고리를 가지고 있는 프로젝트로서, html뿐만아니라 xml, jsp velocity등의 압축도 지원한다.

  • Introduction
  • Overview
  • Compressing HTML
  • Compressing XML
  • Compressing selective content in JSP pages
  • Compressing selective content in Velocity templates
  • Compressing HTML and XML files from a command line
  • Setting up Ant task to compress files



    해당 프로젝트에서 배포한 jar 파일을 프로젝트에 포함한 후 아래와 같은 간단한 
  • 접근으로 압축된 html 문자열을 get 할수 있다.

     private String doHtmlCompress(File htmlFile) {
      StringBuilder lines = new StringBuilder();
      BufferedReader br = null;
      String compressedHtml = null;
      if (htmlFile.isFile()) {
       try {
        br = new BufferedReader(new InputStreamReader(new FileInputStream(htmlFile), "UTF8"));
        String s = null;
        while ((s = br.readLine()) != null) {
         lines.append(s);
        }
        compressedHtml = compressor.compress(lines.toString());
        // compressor = new HtmlCompressor() 외부 메소드에서 이미 인스턴싱함...

        
       } catch (Exception e) {
        System.out.println("Exception on  doHtmlCompress() in HtmlCompressor - File : [ " + htmlFile.getAbsolutePath());
       } finally {
        if(br != null) {
         try {
          br.close();
         } catch (IOException e) {}
        }
       }
      }
      return compressedHtml;
     }



    * 아 정말 두서없이 허접하게, 앞뒤 연관성도 없이 정리했구나 ㅋㅋ 역시나 소설이니 과신은 금물.
    by LeonKim
    2010 07 27







    Web/Javascript 2010/07/27 01:17

    Mac(Leopard,SnowLeopard) + Firefox 에서의 liveconnect 오동작

    liveconnect 란 java와 웹브라우저 javascript와의 통신을 제공하는 기술로서 JSObject 객체를 이용하여 통신이 이루어진다,

    아래 내용은
    Mac(Leopard,SnowLeopard) + Firefox 에서의 liveconnect 오동작에 대한 내용이다.


    applet - javascript간 JSObject객체를 이용하여 applet과 javascript간 통신이 가능하다.
    JSObject객체는 plugin.jar에 기본적으로 포함되어 있다.

    JSObject reference : https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/LiveConnect/JSObject

    아래와 같은 방법으로 JSObject을 얻어낸후 (import하여 직접 JSObject인터페이스에 접근해도 무방하다.) eval, call과 같은 메소드를 이용하여 javascript 메소드의 수행이 가능하다.

    대부분의 플랫폼에서는 정상적으로 liveconnect가 동작하는데, mac(leopard, snowleopard)에서의
    Firefox에서 liveconnect가 정상 동작하지 않는 문제를 발견했다.

                Class<?> jsClass = Class.forName("netscape.javascript.JSObject");
                System.out.println("12");
                Method getWindow = jsClass.getDeclaredMethod("getWindow", new Class[] {
                        java.applet.Applet.class
                   });
                   Object jsObject = getWindow.invoke(null, new Object[] {
                           applet
                   });
                   Method eval = jsClass.getDeclaredMethod("eval", new Class[] {
                        java.lang.String.class
                });
                eval.invoke(jsObject, name+"()");

    다른 플랫폼에서는 상관없으나, mac+ff에서 jsObject를 얻기위하여 수행한 getWidow() 메소드가 항상 null을 return하기 때문에, invoke시 NullPointerException()이 발생한다.

    동일한 코드임에 불구하고, leopard,snowleopard + FF에서만 위와 같은 문제가 발생하는 부분이 나를 약간 괴롭게 만들었다.


    import java.applet.Applet;
    import java.lang.reflect.Method;

    import javax.swing.JApplet;


    public class AppletTest extends JApplet {
        static{
            System.out.println("setSecurityManager");
        }
       
        public void init(){
            System.out.println("init");
        }
       
       
        public void start(){
            System.out.println("start");
            customMethod(this, "alert('test liveconnect')");
        }
       
        public void stop(){
           
        }
       
        public void destroy(){
           
        }
       
       
       
        public void customMethod(Applet applet, String name){
            System.out.println("it's customMethod");
            try{
                Class<?> jsClass = Class.forName("netscape.javascript.JSObject");
                System.out.println("12");
                Method getWindow = jsClass.getDeclaredMethod("getWindow", new Class[] {
                        java.applet.Applet.class
                   });
                   Object jsObject = getWindow.invoke(null, new Object[] {
                           applet
                   });
                   Method eval = jsClass.getDeclaredMethod("eval", new Class[] {
                        java.lang.String.class
                });
                eval.invoke(jsObject, name+"()");
            }
            catch(Exception ex){
                System.out.println("Exception launched");
                ex.printStackTrace();
            }
        }
       
    }



    Sample AppletTest코드에서는 특이한 문제점이 발견되지 않았다.
    쫒고 쫒은 결과 Applet 모듈을 담고 있는 <APPLET> Tag 때문에 발생하는 문제였다.
    이것은 Firefox의 버그인것으로 보인다(다른 플랫폼-윈도우,리눅스등 브라우저에서는 applet tag에 applet모듈을 담고 있어도 정상 동작한다. 심지어 leopard,snowleopard의 크롬, 사파리 마저도 모두 정상 동작 . . .)


    아래와 같은 applet 태그에 포함된 applet 모듈을
        <APPLET archive="AppletTest.jar" CODE="AppletTest.class" WIDTH=100 HEIGHT=100>
            <PARAM NAME=TEXT VALUE="Hi There">
            <P>Hi There<P>
        </APPLET>


    Object 태그로 교체 하면, 정상적으로 jsObject를 얻어 eval, call메소드를 이용하여,
    정상적으로 javascript와 통신이 가능해진다.
    <OBJECT classid="java:com.test.AppletTest" type="application/x-java-applet" archive="AppletTest.jar">
                        <PARAM name="codebase" value="./">
                    <PARAM name="MAYSCRIPT" value="true">
                    <PARAM name="SCRIPTABLE" value="true">
    </OBJECT>



    * 위 정리 내용은 본인의 소설이니, 과신은 금물.
    by LeonKim
    2010 07 26








    Web/Javascript 2010/01/26 11:36

    Dojo Build System


    Status: Draft
    Version: 1.0
    Project owner: (docs) Scott Jenkins
    Available: since 1.0



    Introduction

    도조는 수천의 분리된 파일과 리소스들로서 패키지 시스템으로서 이용이 가능하다. 보통 각 dojo.require 키워드는 서버로 HTTP Call하여 리로스를 물어와서 끝낼때까지 동기적으로 기다린다.그게 다 와야 할일을 할수 있으니 말이다. 이런 과정 (리소스를 요청해서 다 받아온다음에 할일을 하는 그 과정)은 성능에 큰 부담이다.큰 어플리케이션의 경우 결코 받아와야 하는 파일은 작지 않을것이다. 큰 파일은 많은 부담을 준다. 도조는 하나의 file에 모든 도조가 가능한 function을 다 집어 넣지 않았다.
     도조의 모듈이 커진 이래로(dijit, dojox 이 optional하게 추가된 이후로)
    대신 dojo는 build system을 허용하여, Custom Build가 가능도록 지원한다.
     
    Dojo Build System은 packaging툴(ant같은 . .)과 함께 동작이 가능하며, 당신의 모듈의 속도 또한 빠르게 도와준다.

    


    What is a layer?
    Layer이란 single이다.

    Multiple source files로부터 모든 자바 스크립트 코드를 의존성이 걸린 녀석을 모두 포함시켜서 합병 축소시킨 하나의 자바스크립트 파일 을 말한다.이 파일은 표준 HTML 스크립트 태그에 의해 포함되어 사용되어 질수 있다.
     
    당신은 layer 파일을 당신의 웹페이지에 <script> tags로 로드하여 사용할수 있다.브라우저가 스크립트와 동작하려고 Seb Server로부터 모듈을 다운 받아 브라우저 캐쉬에 올릴때 multiple little files 보다 only one larger file을 로딩하는게 웹 페이지를 훨씬 빠르게 한다.

    우리는 dojo.require를 사용하여 우리의 페이지상 필요한 모듈을 페이지에 명시하게 된다.

     dojo.require는 이미 다운된 모듈인지를 확인하고 모듈이 다운된적 있는놈이라면 다시 다운 로드 하지 않는다. (그니깐 layer에 이미 include된놈이라면 다시 load하지 않는 다는 말이다.)

     
    Minification
    - Removing all extra spaces and blank lines
    - Removing comments
    - Making internal variable names (inside of functions, which are not visible to the caller of a function) shorter

     layer dojo Build System 에 의한 each layer 압축은 minification이 있다.

    Minification은 당신의 자바스크립트 코드를 작게 만들어 준다. 그예는 아래와 같다.
    -모든 extra space와 blank line들을 지워준다.,
    - 모든 comments를 지워준다
    - 내부 variable name을 짧게 바꿔준다.


    What does the build system do

    Build system은 무엇을하나
    Build system의 가장 중요한 목적은 Layer 파일의 생성이다.
    Build system은 네가지것으로 성능을 향상 시켜준다.

    1. First, it groups together modules into ''layers''  <<Layers로 그룹 모듈을 모아준다>>
    2. Second, it ''interns'' external non-JavaScript files, such as widget templates which are kept in a separate HTML file during development. Interning makes the file contents a string in the resulting script. <<외부 자바스크립트가 아닌 파일들 결과 script에서 파일 내용을 문자열로 파악할 수 있다.? >>
    3. Third, it minifies the layer with ShrinkSafe. ShrinkSafe removes unneeded whitepsace and comments, and compacts variable names down to smaller ones. This file downloads and parses faster than the original. <<ShrinkSafe를 이용하여 축소한 Layer파일은 불필요한 whitespace와 comments를 삭제한다. compact variable 이름을 작게 만들어준다. 이 Layer파일의 download와 parse는 이전의 원본 보다 빠르다.>>
    4. Finally, it copies all non-layered scripts to the appropriate places. While this doesn't speed anything up, it ensures that all Dojo modules can be loaded, even if not present in a layer. If you use a particular module only once or twice, keeping it out of the layers makes those layers load faster

     <<non-layered scripts를 적절한 place로  copy해준다. 모든 도조 모듈이 Layer에 존재하지 않더라도 로드되어 질수 있다   >>

            만약에 Layer에 없는 모듈을 1~1번 이라도 썻었다면  




    Build Script

    To actually begin your build, you use the build.sh (or build.bat on Windows). For full details on the arguments to build, see build script.

    A typical build command looks something like this:

    build profileFile=../../../js/mylayer action=clean,release version=1.3.0beta3 releaseName=

    This illustrates the most important command line parameters to the build system:

    profileThe profile to be used for the build. .profile.js is appended automatically. The default directory is the <dojo root>/util/buildscripts/profiles directory within the Dojo source distribution, so if your build task specifies profile=thinger, the system will search for <dojo root>/util/build/scripts/profiles/thinger.profile.js. However, most often you will want to reference a profile not within the source tree. To do this, you can specify a profileFile parameter which specifies a path from the current working directory (note, .profile.js is still appended to this file name!).actionThe list of actions to perform. The most common one is release which does the default build magic. The clean option removes previous build artifacts.versionOptional. The version number to "bake in" to the build. When you interrogate dojo.version, this is the number that will be reported.releaseNameBy specifying an empty releaseName parameter, we over-rid the default of dojo, clobbering the generation of a named sub-directory in the output /js/release/ directory. This makes it somewhat simpler to deal with paths at development time, but if you are creating versioned builds, you may chose to specify something like r1234 to indicate a unique build number which you can then check in. Note that specifying a blank releaseName does not work in version of Dojo prior to 1.3.

    Once we've run the build script, all we need to do to use our new-fangled, much-faster layer file is to change the directory we point our <script> tags at. Intead of using the source files located in /js/src/<modulename>, we now look for them in /js/release/<modulename>:

    <!-- dojo.js always provides the package system and base utilities --> <script type="text/javascript" src="/js/release/dojo/dojo.js"></script> <!-- we want dijit.js to be treated like a layer of its own --> <script type="text/javascript" src="/js/release/dijit/dijit.js"></script> <!-- include the rest of the modules we need --> <script type="text/javascript" src="/js/release/acme/mylayer.js"></script>

    TODOC: everything. outline here:

    • summary
    • requirements / setup DONE
    • creating a profile
    • command line arguments
    • special builds: * layers * css
    • file structure

     

        Build를 시작하기 위해서 당신은 build.sh(윈도우에서는 build.bat)를 사용하여야 한다. Build의 Argument는 ~~를 참고해라

        보통 build 명령어는 아래와 같은 형태이다.

            build profileFile=../../../js/mylayer action=clean,release version=1.3.0beta3 releaseName=leon

            

        build profileFile=one action=release version=1.3.0beta3 releaseName=leon  

        

    Build Options

    profile The name of the profile to use for the build. It must be the first part of the profile file name in the profiles/ directory. For instance, to use base.profile.js, specify profile=base. Default: base

    프로파일의 파일명이다 base.profile.js일 경우 프로파일 파일명은 base이다 따라서 profile=base로 해야한다.(그렇게 하면 profiles/base.profile.js를 가지고 빌드 할것이다.) 반드시 프로파일 파일은 profiles/ 디렉토리의 하위에 위치해야한다.
    프로파일 파일이 외부에 있으면 profile옵션 말고 profileFile옵션을 사용해야 한다.
    profileFile A file path to the the profile file. Use this if your profile is outside of the profiles directory. Do not specify the "profile" build option if you use "profileFile" Default: "",

    프로파일 파일 파일이 외부에 있을때 파일 경로를 명시해 주는 옵션이다.
    profileFile 옵션을 쓸때는 profile옵션을 쓰면 안된다.
    action The build action(s) to run. Can be a comma-separated list, like action=clean,release. The possible build actions are: clean, release Default: "help",

    Build Action을 설정해주는 옵션이다.
     , 구분해서 여러 action을 동시에 옵션이 가능하다. (action = clean, release 처럼)
    clean, release가 있다.
    default는 help이다.

    version The build will be stamped with this version string Default: "0.0.0.dev",

    버전 정보를 stamp해주는 옵션이다.
    localeList The set of locales to use when flattening i18n bundles Default: "en-gb,en-us,de-de,es-es,fr-fr,it-it,pt-br,ko-kr,zh-tw,zh-cn,ja-jp",

    로케일 리스트를 설정해주는 옵션
    releaseName The name of the release. A directory inside 'releaseDir' will be created with this name Default: "dojo",

    release 폴더 하위에 생성될 결과 디렉토리의 이름을 설정해주는 옵션이다.
    default는 dojo이다.
    releaseDir The top level release directory where builds end up. The 'releaseName' directories will be placed inside this directory Default: "../../release/",

    release될 결과가 위치할 top 디렉토리 명을 설정해주는 옵션이다 
    이거의 default는 release이다.
    loader The type of dojo loader to use. "default" or "xdomain" are acceptable values." defaultValue: "default",

    어떤 타입의 dojo loader를 사용할지 설정해주는 옵션이다.
    default와 xdomain 옵션이 있는데, default는 default이다(standard loader)
    internStrings Turn on or off widget template/dojo.uri.cache() file interning Default: true,


    optimize Specifies how to optimize module files. If "comments" is specified, then code comments are stripped. If "shrinksafe" is specified, then the Dojo compressor will be used on the files, and line returns will be removed. If "shrinksafe.keepLines" is specified, then the Dojo compressor will be used on the files, and line returns will be preserved. If "packer" is specified, Then Dean Edwards' Packer will be used Default: "",


    Module files를 어떻게 최적화 할지를 정해주는 옵션이다.
    만약에 comments를 정의하면 comment가 제거된다 
    만약에 shrinksafe를 정의하면  dojo compressor가 사용되어 line return이 제거 될 것이다.
    만약에 shrinksafe.keepline를 정의하면 dojo compressor는  line return을 유지 시킬 것이다.
    만약에 packer를 정의하면 default이다;
    layerOptimize Specifies how to optimize the layer files. If "comments" is specified, then code comments are stripped. If "shrinksafe" is specified, then the Dojo compressor will be used on the files, and line returns will be removed. If "shrinksafe.keepLines" is specified, then the Dojo compressor will be used on the layer files, and line returns will be preserved. If "packer" is specified, Then Dean Edwards' Packer will be used Default: "shrinksafe",

    Layer files를 어떻게 최적화 할지를 정해주는 옵션이다.
    만약에 comments를 정의하면 comment가 제거된다 
    만약에 shrinksafe를 정의하면  dojo compressor가 사용되어 line return이 제거 될 것이다.
    만약에 shrinksafe.keepline를 정의하면 dojo compressor는  line return을 유지 시킬 것이다.
    만약에 packer를 정의하면 shrinksafe이다;
    copyTests Turn on or off copying of test files Default: true,

    Test파일의 카피를 on/off할지를 결정하는 옵션이다.
    log Sets the logging verbosity. See jslib/logger.js for possible integer values Default: logger.TRACE,

    로그를 어떻게 할지를 결정하는 옵션이다.
    xdDojoPath If the loader=xdomain build option is used, then the value of this option will be used for the path to Dojo modules. The dijit and dojox paths will be assumed to be sibilings of this path. The xdDojoPath should end in '/dojo' Default: "",

    만약에 loader옵션에서 loader=xdomain로 옵션하였다면, dojo modules의 경로를 위하여 xDojoPath옵션이 필요할것이다.
    dijit과 dojox 경로가 xDojoPath에 주어진데로 여길것이다.
    TOTAL 16,071 TODAY 59