jQuery 객체에 어떤 기능을 추가하고 싶은 경우 플러그인을 작성해서 사용할 수 있다.
1 jQuery 객체 메소드
먼저 jQuery가 작동하는 방식에 대해서 알아 둘 필요가 있다.
$( "a" ).css( "color", "red" );
$
함수를 사용하여 엘리먼트를 선택하면 jQuery 객체를 반환하게 된다. 이 객체는 .css()
, .click()
등과 같은 jQuery의 모든 메소드와 선택한 모든 엘리먼트를 가지게 된다. jQuery 객체는 $.fn
객체로부터 이러한 메소드를 가져와 사용하게 된다. 이 객체는 모든 jQuery 객체 메소드를 포함하기 때문에 플러그인을 작성할 때 이 메소드를 포함게 될 것이다.
[2] 기본 플러그인 작성
선택된 엘리먼트내의 텍스트를 green 색상으로 변경하는 플러그인을 작성해 보자.
$.fn
객체에 greenify
라는 이름의 함수를 작성하면 다른 jQuery 객체 메소드와 같이 사용할 수 있게 된다.
$.fn.greenify = function () {
this.css("color", "green");
};
$("a").greenify();
// 모든 링크를 green 색상으로 변경한다.
주의할 것은 jQuery의 다른 메소드인 .css()
를 사용하기 위해서 $( this )
가 아니라 this
를 사용해야 한다는 것이다. 이것은 greenify
함수가 .css()
와 동일한 객체에 대해서 정의되기 때문이다.
[3] 체인방식으로 메소드 사용하기
jQuery의 특징 중의 하나는 특정 선택자에 대해서 5 또는 6개의 액션을 연결할 때 메소드를 체인방식으로 연속해서 사용할 수 있다는 것이다. 이것은 모든 jQuery 객체 메소드가 최종적으로 원래의 jQuery 객체를 다시 반환하기 때문에 가능한 것이다. 그러나 몇가지 예외는 있다.
예를 들어, .width()
를 매개변수 없이 호출 할 경우에는 해당 엘리먼트의 폭을 반환하여 다른 메소드를 연결해서 사용할 수 없다. 이와 같이 메소드를 체인방식으로 사용하기 위해서는 아래와 같이 코드 한줄을 추가해 주면 된다.
$.fn.greenify = function () {
this.css("color", "red");
return this;
};
$("a").greenify().addClass("greenified");
[4] $ 변수 충돌 피하기
$
변수는 자바스크립트 라이브러리에서 자주 사용하기 때문에 jQuery를 다른 라이브러리와 함께 사용할 경우 jQuery.noConflict()
메소드를 사용하여 jQuery에서 $
변수를 사용하지 못 하도록 해야 한다. 그러나 이와 같은 조치를 취하게 되면 $
를 jQuery 함수의 별칭으로 사용하여 작성한 플러그인은 제대로 동작하지 못하게 된다. 다른 플로그인과 함께 사용하면서 $
별칭을 계속 사용하도록 하기 위해서는 작성하는 모든 코드를 IIFE 내부에 두고 함수로 jQuery
를 넘겨주고 매개변수의 이름을 $
로 명명한다.
(function ($) {
$.fn.greenify = function () {
this.css("color", "red"); return this;
};
}(jQuery));
이와 같이 IIFE
를 사용하는 주된 목적은 자신만의 특별한 변수를 사용할 수 있게 하기 위함이다. 다른 색상의 green을 원할 경우 특정 변수에 저장하여 사용할 수 있다.
(function ($) {
var shade = "#556b2f";
$.fn.greenify = function () {
this.css("color", shade);
return this;
};
}(jQuery));
[5] 플러그인을 최소화하기
플러그인을 작성할 때 가능한한 $.fn
객체 내에 하나의 슬롯(slot, 차지하는 공간)만을 가지도록 하는 것이 좋다. 이것은 자신의 플러그인이 다른 플러그인에 의해서 변경되거나 반대의 경우가 발생할 경우를 줄여 주게 된다.
따라서 아래와 같은 코드는 바람직하지 못한 것이라고 할 수 있다.
(function ($) {
$.fn.openPopup = function () {
// 팝업을 여는 코드
};
$.fn.closePopup = function() {
// 팝업을 닫는 코드
};
}( jQuery ));
따라서, 하나의 슬롯을 가지도록 작성하는 것이 더 좋기 때문에 매개변수를 사용하여 하나의 슬롯이 수행하는 동작을 제어하도록 작성한다.
(function ($) {
$.fn.popup = function (action) {
if (action === "open") {
// 팝업을 여는 코드
}
if ( action === "close" ) {
// 팝업을 닫는 코드
};
};
}( jQuery ));
[6] ‘each( )’ 메소드 사용하기
일반적인 jQuery
객체는 DOM 엘리먼트에 대한 참조값들을 포함하기 때문에 jQuery
객체들은 종종 컬렉션으로 참조되기도 한다. 따라서 특정 엘리먼트에 대해서 데이터 속성 값을 가져오거나 특정 위치를 계산하는 것 같은 조작을 하고자 한다면 .each()
메소드를 사용해서 루프를 사용하도록 한다.
$.fn.myNewPlugin = function () {
return this.each(function () {
// 각 엘리먼트에 대해서 수행할 코드를 여기에 작성한다.
});
};
주의해서 볼 것은 this
가 아니고 .each()
의 결과를 반환한다는 것이다. .each()
메소드는 체인방식으로 사용할 수 있기 때문에 이 메소드가 반환하는 this
를 반환하게 되는 것이다. 이 방법이 지금까지 사용했던 것보다 체인방식을 유지하기가 더 용이하다.
[7] 옵션 사용하기
플러그인이 점점 더 복잡해지면 옵션을 넘겨 주어 플러그인의 설정을 쉽게 할 수 있도록 하는 것이 좋다. 특히 옵션이 많을 경우 가장 손쉽게 구현할 수 있는 방법은 옵션 객체를 사용할 것이다. 지금까지 작업한 greenify 플러그인을 변경해서 옵션을 받을 수 있도록 하자.
(function ($) {
$.fn.greenify = function (options) {
// 기본 옵션을 지정하는 가장 손쉬운 방법
var settings = $.extend({
// 기본 옵션
color: "#556b2f", backgroundColor: "white"
}, options );
// settings 변수를 이용하여 색상값을 변경한다
return this.css({
color: settings.color, backgroundColor: settings.backgroundColor
});
};
}( jQuery ));
사용예:
$( "div" ).greenify({
color: "orange"
});
[8] 종합해서 보기
지금까지 논의되었던 방법을 이용해서 작성한 플러그인 예는 아래와 같다.
// 사용예 $( "a" ).showLinkLocation();
(function ($) {
$.fn.showLinkLocation = function () {
this.filter("a").each(function () {
var link = $(this); link.append(" (" + link.attr("href") + ")");
});
return this;
};
}(jQuery));
이 플러그인은 컬렉션 내의 모든 a
태그를 찾아서 href
속성 값을 괄호 안에 추가해 태그 뒤에 붙여 준다.
<!-- 플러그인 호출 전 -->
<a href="page.html">Foo</a>
<!-- 플러그인 호출 후 -->
<a href="page.html">Foo (page.html)</a>
이것은 아래와 같이 코드를 최적화할 수 있다.
(function ($) {
$.fn.showLinkLocation = function () {
this.filter("a").append(function () {
return " (" + this.href + ")";
});
return this;
};
}(jQuery));
콜백을 호출할 수 있는 .append()
메소드를 사용했고 콜백이 반환하는 값이 각 엘리먼트에 붙게 되는 값이 된다. 또한 href
속성값을 얻기 위해서 .attr()
메소드를 사용하지 않았다는 것을 주의해서 보자. DOM API의 href
메소드를 사용하면 쉽게 href
속성값을 얻을 수 있기 때문이다.