제이쿼리 플러그인 만들기

jQuery 2017. 8. 28. 11:12

728x90
반응형

jQuery 플러그인 만드는 방법을 포스팅 합니다.


저는 NEXTREE 에서 보고 배웠습니다.

알기 쉽고 간단하게 글을 쓰셔서 정말 감사합니다.

 




1) 플러그인을 만드는 이유

  • 일관된 코드 스타일을 유지
  • jQuery의 기반 코드를 잘 활용


예제 1)

1
$(this).parents().find("input").val();
cs


셀렉터는 엘리먼트 확장 집합의 형태로 표현하고 있습니다. 그리고 jQuery 메소드와 메소드 체인을 셀렉터(확장 집합)에 적용합니다. 이런 코드 스타일은 jQuery를 적용한 스크립트에서 대표적으로 사용되는 스타일 입니다.


개발할 때 이러한 스타일을 반드시 고수해야 하는건 아닙니다. 이와 같은 다른 스타일로도 작성이 가능합니다.하지만 일반적으로 경험 많은 개발자들은 프로젝트를 진행하거나, 협업을 하는 경우 코드의 일관성을  유지하는 것이 좋다고 조언합니다. 자신의 개발하는 코드를 일반 자바스크립트 함수가 아닌 jQuery 플러그-인으로 제작하면 사이트 전체에 일관된 코드 스타일을 유지할 수 있습니다. 코드 스타일이 일관된다면 코드에 대한 이해가 쉽고 유지보수에도 용이합니다.


jQuery 플러그-인을 제작하는 두번째 이유는 jQuery가 제공하는 강력한 기능(셀렉터, 메소드)을 활용할 수 있다는 점입니다. 이미 jQuery에는 우리에게 익숙하고, 강력한 도구가 많습니다. 이를 두고  처음부터 다시 코드를 작성할 이유가 없습니다.


결론적으로 jQuery 도구 재사용이 가능한 스크립트 환경에서 는 jQuery 플러그-인으로 작성하는 것이 현명한 방법이라 할 수 있습니다.




2) 플러그인 제작


간단하게 jQuery 플러그-인을 제작해 보겠습니다. 자바스크립트 함수를 jQuery Object 인스턴스 프로퍼티로 추가하여 제작했습니다. 그 내용은 예제 2와 같습니다.


예제 2)

1
$.say = function(what) {alert('I Say ' + what);}
cs



마치 자바스크립트 함수를 선언하고 객체 프로퍼티로 할당하는 것과 같이 쉽고 단순합니다.




3) 플러그인 에서 ['$'별칭 사용]


jQuery를 사용하는 개발자라면 대부분 '$'별칭을 사용합니다. 코드 작성시 편리하게 사용되고 '$'로 작성된 코드가 보다 읽기 편하기 때문입니다. 하지만 플러그-인에서 '$'별칭을 사용할 수 있다고 단정지을 수 없습니다. 완성된 플러그-인이 배포되어 다른 환경에서 사용이 된다고 가정해 보겠습니다. 만약 그런 환경이 $.noConflict() 메소드를 사용하여 '$' 별칭을 모두 양도 한다면 위와 같이 작성된 플러그-인은 작동하지 않습니다.


예제 3)

1
jQuery.say = function(what) {alert('I Say ' + what);}
cs


예제3과 같이 작성한다면 '$'별칭의 충돌을 피할 수 있습니다. 하지만 이미 '$'별칭에 익숙하고 그 장점을 포기할 수 없으면 예제4와 같이 정의 합니다.


예제 4)

1
2
3
(function($) {
    $.say = function(what) { alert('I Say ' + what); }
})(jQuery);
cs4



이처럼 '$'를 플러그-인 내부의 지역 변수로 정의하여 사용하면 충돌의 피하면서도 '$'별칭을 사용할 수 있습니다. 이렇게 함수를 정의해 바로 사용하는 문법을 즉석 호출 함수표현식(IIFE, Immediately Invoked Function Expression)이라 합니다. 앞으로 보여드릴 플러그-인 예제는 이러한 형식을 사용하고 있습니다.



[전역함수]


jQuery 전역 함수는 실제로 jQuery 객체의 메소드지만, 현실적으로 보면 jQuery 네임스페이스 함수 입니다. 따라서 jQuery 네임 스페이스에 함수를 작성하면 일반 전역 함수와의 충돌 가능성은 없습니다. 단 jQuery 메소드와 이름이 충돌하는지의 여부만 신경써주면 됩니다. jQuery 라이브러리에서 제공하는 전역함수 중에는 $.each(), $.map(), $.grep()과 같은 다양한 유틸리티 메소드(utility method)가 있습니다.

 

간단한 유틸리티 메소드를 직접 제작해 보겠습니다.

 

예제 5)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(function($){
    $.sum = function(array){
        var total = 0;
        $.each(array, function(index, value){
            value = $.trim(value);
            value = parseFloat(value) || 0;
 
            total += value;
        })
        return total;
    }
})(jQuery);
 
(function($){
    $.average = function(array){
        if($.isArray(array)){
            return $.sum(array) / array.length;
        }
        return '';
    }
})(jQuery);
cs

 

배열을 받아 총계를 리턴하는 함수와 평균을 리턴하는 함수를 jQuery 객체의 프로퍼티에 추가하여 간단히 플러그-인을 제작했습니다. 이 플러그-인들은 예제 6과 같이 사용할 수 있습니다.

 

예제 6)

1
2
$.sum([1,2,3]);
$.average([1,2,3]);
cs

 

이렇게 제작된 전역함수는 jQuery 네임스페이스 내 같은 이름을 갖는 함수와 충돌할 수 있습니다. 이를 예방하기 위해 전역함수를 하나의 객체로 캡슐화(encapsulation) 할 수 있습니다.

 

 

 

 

 

예제 7)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(function ($) {
    $.mathUtils = {
        sum: function(array) {
            var total = 0;
            $.each(array, function(index, value) {
                value = $.trim(value);
                value = parseFloat(value) || 0;
 
                total += value;
            });
            return total;
        },
        average: function(array) {
            if($.isArray(array)) {
                return $.mathUtils.sum(array) / array.length;
            }
        return '';
        }
    };
})(jQuery);
cs

 

예제7과 같은 패턴은 jQuery.mathUtils 네임스페이스를 생성하고 정의된 함수를 jQuery 객체의 프로퍼티인 mathUtils 객체의 메소드가 됩니다. 이렇게 정의된 플러그인은 예제8과 같이 사용할 수 있습니다.

 

예제 8)

1
2
$.mathUtils.sum([1,2,3]);
$.mathUtils.average([4,5,6]);
cs

 

 

 

 

[객체 메소드]

 

앞에서 jQuery 전역함수를 만들어 보았습니다. 하지만 대부분의 jQuery 내장 기능은 객체 메소드로 제공됩니다.

이번에는 DOM일부를 조작하는 함수인 객체 메소드를 제작해 보겠습니다.

 

예제 9)

1
2
3
4
5
6
7
8
9
(function($){
    $.fn.swapClass = function(class1, class2){
        if(this.hasClass(class1)){
            this.removeClass(class1).addClass(class2);
        }else if(this.hasClass(class2)){
            this.removeClass(class2).addClass(class1);
        }
    }
})(jQuery);
cs

 

jQuery 객체를 확장했던 전역함수와는 달리 객체 메소드는 jQuery.fn 객체를 확장하고 있습니다.(jQuery.fn은 jQuery.prototype의 별칭입니다.)

 

 

위와 같이 제작한 플러그인은 지정된 DOM 엘리먼트의 class를 변경하는 기능을 제공하고 있습니다. 사용하는 방법은 예제10 과 같습니다.

 

 

예제 10)

1
$('div').swapClass('one''two');
cs

 

 

 

기존의 <div>엘이먼트의 class가 'one'이라면 'two'로 'two'라면 'one'로 변경이 된다고 예측할 수 있습니다.

 

 

 

[묵시적 반복]

 

앞에서 소개된 객체 메소드는 DOM 엘리먼트 집합중 최초의 엘리먼트만 적용이 됩니다. 하지만 일반적으로 사용되는 jQuery 함수는 jQuery 선택자 표현식이 0개 또는 1개 이상의 요소와 매칭이 됩니다. 즉, jQuery 함수는 다수의 엘리먼트에 함수의 기능이 적용이 되어야 합니다. 따라서 플러그-인을 설계할 때 jQuery 선택자가 복수인 경우를 모두 감안해야 합니다.

.each() 메소드를 이용하여 묵시적인 반복(implicit iteration)을 수행하도록 플러그-인을 수정하겠습니다.

 

예제 11)

1
2
3
4
5
6
7
8
9
10
11
12
(function($){
    $.fn.swapClass = function(class1, class2){
        this.each(function(){
            var $element = $(this);
            if($element.hasClass(class1)){
                $element.removeClass(class1).addClass(class2);
            }else if($element.hasClass(class2)){
                $element.removeClass(class2).addClass(class1);
            }
        })
    }
})(jQuery);
cs

 

 

 

예제11에서 this 키워드의 의미에 주의해야 합니다. swapClass 메소드 안에서의 this는 jQuery 객체를 의미하고 .each() 메소드의 콜백함수에 사용된 this 키워드는 DOM 요소를 의미합니다. 이렇게 구현된 플러그-인은 DOM내의 모든 <div> 엘리먼트에 swapClass() 메소드를 적용합니다.

 

 

 

[메소드 체인]

 

앞에서 '묵시적 반복' 규칙을 준수한 예제11에서도 부족함이 보입니다. 이 플러그-인을 사용할 경우 선택자에 swapClass()를 적용한 후 다른 메소드를 적용하려면 다시 선택자에 해당 메소드를 호출하는 새로운 문장을 작성해야만 합니다.

 

 

 

 

그러나 예제1과 같이 일반적으로 jQuery 메소드는 메소드 체인을 사용하고 있습니다. 다른 메소드들과 함께 자유롭게 체인을 사용하게 되면 코드를 간결하게 만드는 데에도 도움이 됩니다. 메소드 체인이 가능하도록 다음과 같은 규칙을 추가하겠습니다.

  • 특정한 값을 리턴할 의도가 없다면 선택 요소를 리턴한다.

위의 규칙을 적용하여 메소드 체인을 사용할 수 있도록 수정하겠습니다. 그 결과는 예제12-1와 같습니다.

 

 

예제 12-1)

1
2
3
4
5
6
7
8
9
10
11
12
(function($){
    $.fn.swapClass = function(class1, class2){
        return this.each(function(){
            var $element = $(this);
            if($element.hasClass(class1)){
                $element.removeClass(class1).addClass(class2);
            }else if($element.hasClass(class2)){
                $element.removeClass(class2).addClass(class1);
            }
        })
    }
})(jQuery);
cs

 

예제 12-2)

1
$('div').swapClass('one''two').css('color''#0000ff');
cs

 

 

메소드 체인은 위와 같이 DOM 요소를 리턴하는 것만으로도 간단히 구현됩니다. 묵시적 반복과 메소드 체인과 같은 규칙을 준수함으로서 기존 jQuery 메소들과의 일관성을 유지할 수 있고 플러그-인 개발자 외 다른 개발자들이 쉽게 이해하고 사용할 수 있습니다.

 

 

 

[파일명 짓기]

 

제작된 플러그 인을 파일로 저장시 파일이름 또한 파일명과의 충돌의 고려해야 합니다. 아래 규칙은 jQuery 팀에서 추천하는 명명 규칙입니다.

 

  1. 접두어로 jquery.를 사용한다.
  2. 이어서 플러그-인 이름을 적는다.
  3. 선택적으로 플러그-인 메이저와 마이너 버전값을 적는다.
  4. .js로 파일 이름을 끝맺는다.
  5. 제작된 플러그-인의 이름이 'nextree'라면 jquery.nextree-1.0.js  와 같은 파일명을 적용하면 되겠습니다.



-----------------------------------------------------------------------------------------------------


자바스크립트 프로토타입 : http://recoveryman.tistory.com/367

자바스크립트 메소드 체이닝 : http://recoveryman.tistory.com/368

반응형