jQuery는 많은 플러그인들이 존재한다.
그 자체로도 대단한 라이브러리이지만 많은 플러그인들이 더 대단하도록 만들어 준다.
자..
jQuery 플러그인!
나도 만들어 보자.
◎ 플러그인에서 $ 별칭 사용
= 플러그인을 사용하기 위해서는 jQuery 라이브러리가 로드됐다고 가정할 수 있다. 그렇다고 해서 $ 별칭을 사용할 수 있다라는 점에 대해서는 가정할 수 없다. $.noConflict() 메서드로 별칭에 대한 제어를 양도할 수 있기 때문.
= $를 플러그인 내부의 지역 변수로 정의해 사용하는 것이 좋다.
(funtion($) {
// 코드 표시
})(jQuery);
= 위와 같이 정의하여 사용하도록 한다. 이렇게 함수를 정의해 바로 사용하는 문법을 즉석 호출 함수 표현식(IIFE, Immediately Invoked Function Expression)이라 한다.
◎ 새 전역함수 추가
= jQuery 자체 기능 중 일부는 전역함수. jQuery 객체의 메서드지만, 현실적으로 보면 jQuery 네임스페이스(namespace)의 함수다.
= 일반 전역함수일 경우 충돌할 가능성을 염두에 둬야 하지만 jQuery 네임스페이스에 함수를 두면 jQuery만 신경쓰면 되므로 충돌 염려를 줄일 수 있다.
예) sum 메서드 추가하기
(function ($) {
$.sum = function(obj) {
// 코드 표시
};
})(jQuery);
◎ 여러 함수 추가하기
= 플러그인이 하나 이상의 전역함수를 가질 때는 따로 선언해 주면 된다.
예) sum, avg 메서드 추가하기
(function ($) {
$.sum = function(obj) {
// 코드 표시
};
$.avg = function(obj) {
// 코드 표시
};
})(jQuery);
= $.extend() 함수를 이용하여 함수를 정의할 수도 있다.
(function ($) {
$.extend({
sum : function(obj) {
// 코드 표시
},
avg : function(obj) {
// 코드 표시
}
});
})(jQuery);
= 하지만 아직도 다른 jQuery 플러그인에 정의된 함수 이름과 충돌할 가능성이 있다. 이런 문제를 해결하는 가장 좋은 방법은 정해진 플러그인에서 선언할 모든 전역함수를 하나의 객체로 캡슐화(encapsulation) 하는 것이다. - 함수와 그 함수와 연관된 함수를 하나로 묶어주도록 한다.
(function ($) {
$.mathUtils = {
sum : function(obj) {
// 코드 표시
},
avg : function(obj) {
// 코드 표시
}
});
})(jQuery);
= 여기에서 선언하는 전역함수를 위한 별도의 네임스페이스 mathUtils를 생성
= 호출시에 $.mathUtils.sum(), $mathUtils.avg() 형식으로 사용한다.
= 고유한 플러그인 이름을 사용하여 전역함수 이름이 충돌하는 일을 막도록 한다.
◎ jQuery 객체 메서드 추가
= DOM 일부를 조작하는 함수를 작성하려 한다면 객체 메서드를 새로 추가하는 방식이 적절
jQuery.fn.myMethod = function() {
// do Something
}
= jQuery.fn 객체는 jQuery.prototype의 별칭
= $('div').myMethod() 형식으로 사용가능
객체 메서드 컨텍스트
= 플러그인 메서드에서 this 키워드는 현재 jQuery 객체를 가리킨다.
= this 키워드를 사용해 임의의 jQuery 메서드를 호출하거나 DOM 노드 작업 가능
묵시적 반복
= jQuery 선택자 표현식이 0개, 또는 1개 이상의 여러개의 요소와 매치될 수 있기 때문에 플러그인 메서드를 설계할 때는 이런 시나리오를 감안해야 한다.
= 매치되는 요소의 개수와 관계없이 모두에게 적용하는 가장 간단한 방법은 메서드 컨텍스트에 항상 .each()를 호출 하는 것
= .each() 메서드는 묵시적인 반복(implicit iteration)을 수행, 이는 플러그인과 jQuery의 기본 메서드 사이의 일관성을 유지하는 데 중요하다.
= .each() 내부의 this는 각 DOM 요소를 차례로 가리킨다
※ this의 의미 : 객체 메서드 자체에서는 jQuery 객체, .each() 호출에서는 DOM 요소
메서드 체인
= jQuery 사용자는 체인 기능을 사용할 수 있어야 한다.
= this에 대해 .each()를 적용한 후 해당 결과를 반환(return)하면 된다.
◎ 메서드 파라미터
파라미터 맵
= 맵은 각 파라미터에 대해 시각적인 레이블을 제공, 파라미터의 순서를 지키지 않아도 된다.
= jQuery API와 유사하므로 사용상의 일관성을 더 높이는 효과
기본 파라미터 값
= 맵에서 값을 지정하지 않은 파라미터는 기본값으로 대체
= 메서드 내부에 새로운 맵(예 - defaluts)을 정의, 유틸리티 함수 $.extend()를 사용하여 전달받은 맵(예 - opts)을 defaluts 맵에 덮어쓰며 opts에서 지정하지 않은 값은 그대로 두고 지정된 값만 덮어쓴다.
콜백 함수
= 플러그인 자체에 지나친 부담을 줄여주면서 많은 유연성을 부여
= 콜백 함수를 사용하려면 파라미터를 함수 객체를 전달받아 적당한 방식으로 호출하도록 구현해야 함
커스터마이즈할 수 있는 기본값
= 기본값에 대한 정의를 메서드 밖으로 옮기고, 메서드 밖에서도 접근할 수 있는 곳에 위치시킨다.
(function($) {
$.fn.shadow = function(opts) {
var options = $.extend({}, $.fn.shadow.defaults, opts);
// ...
};
$.fn.shadow.defaults = {
copies : 5,
opacity : 1,
copyOffset : function(index) {
return {x : index, y : index}
}
};
})(jQuery);
= $.fn.shadow.defaults로 직접 참조
= 또한 $.extend()를 호출하는 방식도 달라져야 한다. 비어있는 맵 {}을 $.extend()에 첫 번째 인자로 전달해 새로운 맵이 변경되게 해야 한다.