출처 : http://lazygyu.tistory.com/42

jQuery는 메소드와 함수를 플러그인으로 넣을 수 있는 방법을 제공합니다. 기본적으로 다운로드 되는 대부분의 메소드와 함수들은 jQuery 플러그인 구조를 이용해 만들어져 있습니다.

플러그인은 두 단계를 거쳐 만듭니다. 첫번째는 공용(public) 함수와 메소드를 작성하는 것입니다. 예를 들면 아래와 같습니다.

jQuery.fn.debug = function() {
  return this.each(function(){
    alert(this);
  });
};
jQuery.log = function(message) {
  if(window.console) {
     console.debug(message);
  } else {
     alert(message);
  }
};

코더들은 다음과 같이 당신의 새 플러그인을 호출할 수 있습니다.

$("div p").debug();

혹은 함수를 사용할 수 있습니다.

try {
  // do some error prone stuff
} catch(exception) {
  $.log(exception);
}

몇가지 기억해 두어야 할 중요한 사안이 있습니다.

  • 파일명을 jquery.[플러그인명].js 로 짓도록 합니다. 예 : jquery.debug.js
  • 모든 새로운 메소드는 jQuery.fn 개체에 종속되도록 하고, 모든 함수는 jQuery 개체에 종속되게 합니다.
  • 메소드 내에서 'this' 인스턴스는 현재 jQuery 개체를 가리킵니다.
  • 새로 덧붙인 모든 메소드와 함수는 반드시 세미콜론(;)으로 끝나야 합니다 - 그렇지 않으면 파일을 압축할 때 코드가 깨지기 때문입니다.
  • 메소드는 특별히 명시된 상황이 아닌 한 반드시 jQuery 개체를 반환해야 합니다. 
  • this.each 를 사용해서 현재 엘리먼트 셋에 접근해야 합니다 - 이렇게 하면 코드는 깔끔하고 호환성이 높아집니다.
  • 항상 메소드를 $ 대신에 jQuery 에 바로 추가하도록 합니다. 그래야 사용자는 noConflict() 를 통해 자신만의 이름을 사용할 수 있습니다. 사용자 별명 섹션 아래를 읽도록 합니다. 고상한 해결책은 $를 내부에서 사용하되, 메소드는 첫째 jQuery 개체에 추가하는 것입니다.

만일 플러그인의 전체적인 모습이 어떻게 이루어졌는지 궁금하다면, 플러그인 탐색 이나 jQuery 소스 코드를 볼 수 있습니다.

위쪽의 내용은 작고 단순한 플러그인에는 충분하지만 다른 경우, 좀 더 지능적인 방법이 필요합니다.

목차

개체 내의 정적인 함수 모으기

만약 여러개의 정적인 메소드가 필요하다면, 하나의 개체에 그것들을 추가해야 합니다. 예를 들어 다음과 같이 시작했다면,

jQuery.logError = function() { ... };
jQuery.logWarning = function() { ... };
jQuery.logDebug = function() { ... };

아래와 같이 바꿉니다.

jQuery.log = {
  error : function() { ... },
  warning : function() { ... },
  debug : function() { ... }
};

이렇게 해서 네임스페이스가 어지럽혀지지 않고, 많은 문제를 회피할 수 있습니다.

변수 숨기기

반복문 내에서 플러그인 메소드를 정의하는 데는 일일이 열거하는 것 말고도 다른 방법이 있습니다.

예를 들면:

var newMethods = {
  check       : function() { ... },
  uncheck     : function() { ... },
  toggleCheck : function() { ... }
};
jQuery.each(newMethods, function(i) {
  jQuery.fn[i] = this;
});

만약 newMethods 변수를 다른 코드로부터 숨기고 싶다면, 저 코드를 즉시 실행되는 함수로 감쌉니다. (변수의 종결부분을 만듭니다)

(function() {
  var newMethods = {
    check       : function() { ... },
    uncheck     : function() { ... },
    toggleCheck : function() { ... }
  };
  jQuery.each(newMethods, function(i) {
    jQuery.fn[i] = this;
  });
})();

설정

수많은 매개변수를 일일이 열거하지 않아도 사용할 수 있도록 플러그인을 디자인하는 연습을 하는 것이 좋습니다. 가능한한 유연하게 만들기 위해서는, 재치있는 기본값을 가진 몇몇 설정을 제공해야 합니다. 매개변수로 URL이 항상 필요하고, 'name'(문자열), 'size'(숫자), 'global'(논리) 의 선택사항을 가진 플러그인을 고찰해봅시다.

플러그인은 아래와 비슷하게 만들어질겁니다.

jQuery.fn.pluginName = function(url, options) {
  // define defaults and override with options, if available
  // by extending the default settings, we don't modify the argument
  settings = jQuery.extend({
     name: "defaultName",
     size: 5,
     global: true
  }, options);

  // do the rest of the plugin, using url and settings
}

이 플러그인은 아래처럼 선택사항 없이 사용할 수 있습니다.

$('selection').pluginName('mypage.php');

혹은 두세개의 선택사항과 함께 사용할 수도 있습니다.

// override defaults for name and size, but not global
var options = {
  name: "foobar",
  size: 10
}
$('selection').pluginName('mypage.php', options);


관련 읽기: Mike Alsup 은 굉장한 플러그인 개발 패턴을 작성했습니다. 모든 주석을 읽어보세요. 샘플 코드에는 약간의 버그가 있습니다.

jQuery.extend 를 사용하여 jQuery를 확장하기

위쪽 섹션에서, 우리는 플러그인 설정 개체를 확장하기 위해 jQuery.extend(setting, options)를 사용했습니다. 이제, 두개나 그 이상의 개체 대신에 단 하나의 개체만을 이용해서, 우리는 jQuery.extend 함수를 매개 변수를 포함해 jQuery 개체 자체를 확장하는 데 사용할 수 있습니다. 이것은 jQuery의 다른 모든 외관에 가깝게 무언가를 추가할 수 있도록 허락합니다. 새 메소드를 예로 들면:

jQuery.fn.extend({
  check       : function() { ... },
  uncheck     : function() { ... },
  toggleCheck : function() { ... }
});

하지만 jQuery.extend 를 jQuery 내에서 정의된 다른 개체를 확장하는 데 사용할 수도 있습니다. (예를 들면 새로운 셀렉터를 추가하는 것과 같은)

jQuery.extend(jQuery.expr[":"], {
  text     : "a.type=='text'",
  radio    : "a.type=='radio'",
  checkbox : "a.type=='checkbox'"
});

애니메이션 제작하기

플러그인이 확정된 이벤트를 위해 애니메이션을 사용해야 할 수도 있습니다. 예를 들어 탭 플러그인은 탭을 변경할 때 페이드(fade)나 슬라이드(slide) 애니메이션을 사용합니다. 애니메이션을 필요에 따라 재작성하는 것은 animate 메소드를 사용하면 간단합니다. (자세한 내용은 API 문서를 참조하세요) 아래의 예제는 기본적으로 페이드를 사용합니다.

jQuery.fn.foobar = function(settings) {
  settings = jQuery.extend({
    animation: {opacity: "hide"}
  }, settings);
  // use the animation setting as a parameter for animate
  jQuery(...).animate(settings.animation);
}

애니메이션을 위한 설정을 넘겨줌으로써 슬라이드를 사용할 수 있습니다.

jQuery(...).foobar({
  animation: {height: "hide"}
});

개인별 명칭

플러그인 코드 내에서 "$"를 사용하지 않는 것인 좋은 상태입니다. 이 것은 jQuery 와 플러그인 사용자에게 "$"를, 예를 들면 "jQ" 같은 것으로 바꿀 수 있게 해줍니다. 이것은 "$"를 사용하는 다른 라이브러리나 프레임워크를 사용하기 위해선 꼭 필요합니다.

물론, $ 는 아주 편리한 단축명칭이고, 이 것을 사용하지 않는 대신에 우리는 이 것의 존재도 신뢰해선 안됩니다. 대신, 우리는 간단하게 자신만의 별칭 (이 것을 "$"라고 부릅시다)을 코드에 사용할 수 있습니다.

플러그인 코드 내에서의 명칭

아래의 방법은 모든 플러그인 코드 내에 함수를 하나 만들고 즉각 실행시킵니다. 구조는 아래와 같이 생겼습니다.

(function() {
  // put plugin code here
  var xyz; // xyz is NOT a global variable, it is only visible inside this function
})(); // execute the function immediately!

부가적인 괄호는 반드시 필요합니다! 괄호 없이는 무기명 함수를 실행시킬 수가 없습니다.

자, 이제 재밌는 부분입니다.

(function($) {
  // plugin code here, use $ as much as you like
})(jQuery);

우리는 "jQuery"를 함수에 넘겨주어 어떤 명칭이든 우리가 좋아하는 것으로 사용할 수 있게 되었습니다. 그러므로 "$" 대신 JavaScript 변수명으로 가능한 다른 어떤 값이든 사용할 수 있습니다.

이것을 사용하는 플러그인을 보려면 툴팁 플러그인을 참조하세요.

페이지 코드 내에서의 명칭

플러그인 사용법을 그리는 예제를 만들기 위해 jQuery 코드를 작성할 때, 향후 호환이 가능하게 만들어주는 기술에 대해 고심할지도 모릅니다. 많은 jQuery 예제 코드들(많은 플러그인을 포함한 광범위한 예제들)은 $ 를 사용하여 작성되었습니다. 이것은 당신의 플러그인을 사용하려는 다른 사람들이 $를 다른 용도로 이미 사용하고 있을 때 문제가 될 수 있습니다.

이것을 방지하기 위해, 예제 코드를 DOM ready 이벤트 핸들러에 써 넣을 수 있습니다.  첫번째 인자는 함수 내에서 $ 가 될 수도 있고, 다른 어떤 것도 사용할 수 있으며, 이 것은 해당 함수 내에서 jQuery 의 별칭으로 사용됩니다.

 jQuery(function($) {
   // your code using $ alias here
 });

이 방법으로, jQuery 를 한 번만 타이핑하고도 ready 핸들로 코드 내에서 별칭을 안전하게 사용할 수 있습니다. 더 많은 정보를 원하면, 이 기술에 대한 경고를 포함한 jQuery 와 다른 라이브러리를 함께 사용하기를 보도록 합니다.

함께 넣기

아래에 당신의 플러그인을 개발하기 시작하는 데 사용할 수 있는 짧은 샘플 코드가 있습니다.

 (function($) {
 
   $.fn.myPlugin = function(settings) {
     var config = {'foo': 'bar'};
 
     if (settings) $.extend(config, settings);
 
     this.each(function() {
       // element-specific code here
     });
 
     return this;
 
   };
 
 })(jQuery);


이 예제 내에서 "config" 변수는 플러그인을 위한 기본적인 설정을 담은 개체로 사용됩니다. (예를 들면, "{'speed':1000}"과 같은.) 이것은 함수가 호출될 때 선택적으로 넘겨진 "settings" 개체를 확장해 사용합니다.

중간의 each() 메소드는 미리 jQuery 셀렉터를 통해 선택해 플러그인으로 넘겨진 개체들에 대한 반복입니다. 예를 들어, 만약 플러그인이 아래와 같이 호출되었다면,

 $('p').myPlugin();

each() 메소드는 페이지 내의 모든 문단 태그를 반복하게 됩니다.

이 예제에서 가장 중요한 부분은 "return this;" 입니다. 이것은 플러그인이 호출 될 때 남아있을지도 모르는 jQuery 체이닝을 보장하기 위해 필요합니다. 다시 말해 사람들이 당신의 플러그인을 호출한 뒤에 다른 메소드를 덧붙일지도 모른다는 뜻입니다.

 $.myPlugin({'foo': 'bar'}).fadeOut();
 
댓글은 로그인 사용자만 작성 가능합니다. 로그인하기