본문 바로가기
Javascript/jQuery

jQuery 플러그인

by 카리3 2020. 6. 28.

jQuery 플러그인

jQuery 플러그인은 jQuery의 프로토타입 객체를 확장하는 새로운 메소드를 추가하는 것이다. jQuery 기능을 추가한다는 개념이지만, jQuery 기능을 모두 사용할 수 있는 기능을 만든다고 생각하면 된다.

플러그인 참고 사이트

http://plugins.jquery.com/

http://www.jqueryrain.com/

http://www.htmldrive.net/

http://www.unheap.com/

 

플러그인을 만드는 이유

1. jQuery 라이브러리와 일관된 코드스타일 유지

2.  jQuery 기반코드 활용

jquery의 selector와 메서드 활용

 

1. jQuery의 기본 동작 방식

$("a").css("color", "red");

이 코드는 먼저 $ 함수를 사용하여 모든 <a> 태그를 선택합니다. ( $("a"); 이 함수는 실행후 jQuery 객체를 반환합니다. 반환된 jQuery 객체에 대해서 .css("color", "red") 를 실행해서 색깔 스타일을 red 로 지정합니다. 이때 jQuery 객체는 $.fn 객체로부터 필요한 메소드(.css() 등)를 가져오게 됩니다. 우리가 jQuery 플러그인을 만든다는 것은 $.fn 객체에 새로운 메소드를 만들어 넣는 것이 됩니다.(실제 $.fn 은 $.prototype 입니다.)

2. 기본적인 플러그인 작성

// 플러그인 정의 
$.fn.greenify = function() { 
	this.css("color", "green"); 
  }; 
// 플러그인 호출 
$("a").greenify();

플러그인 정의 내에서 .css() 함수를 호출할때 $(this) 가 아니라 this.css() 로 호출 합니다. 이것은 greenify 함수가 .css() 함수와 같은 객체의 일부분이기 때문입니다.(여기에서 this 는 jQuery 객체가 됩니다.)

※ 참고 - $(this)와 this 의 차이점

this 라는 키워드는 자기 자신을 가리키는 객체 참조 입니다. 자바스크립트에서 this를 사용할 때 주의해야 할점은 현재 실행되고 있는 scope 에서의 자신을 가리킨다는 것입니다. 다음 코드를 보겠습니다. id가 btn 인 요소를 클릭했을때 실행될 코드 입니다. 클릭했을때 실행되는 function(){} 에서 this 는 클릭된 요소가 됩니다. $(this) 는 this가 가키리는 요소를 감싼 jQuery 객체를 만들기 위해서 사용됩니다.

$("#btn").click(function() {
    this;    // id가 btn 인 요소 자체가 됩니다.
    $(this); // id가 btn 인 요소는 가지고 있는 jQuery 객체가 됩니다.
});

 

3. 메서드 체이닝 (Chaining)

jQuery를 사용할 때 선택된 요소에 대하여 몇가지 작업을 링크하여 사용하는 경우가 많습니다. 이것은 메소드가 jQuery 자신을 반환하기 때문입니다. 우리의 플러그인이 이렇게 사용될 수 있도록 하는 방법은 메소드 끝에서 자신을 반환하도록 하면 됩니다.

$.fn.greenify = function() { 
	this.css( "color", "green" ); 
    return this; 
  } 
  
  $("a").greenify().addClass("greenified");

4. $ 별칭을 보호하고 범위(Scop)를 추가하기

jQuery 에서 사용하는 $ 변수는 다른 라이브러리들도 많이 사용합니다. 그래서 변수가 충돌하여 동작을 하지 않을 가능성이 항상 있습니다.(jQuery의 경우 $ 변수는 jQuery 변수의 별칭 입니다.) 우리가 만드는 플러그인이 이러한 충돌을 피할 수 있도록 즉시 호출 함수 표현을 사용해서 감싸 줍니다.

(function($) { 
  $.fn.greenify = function() { 
      this.css("color", "green"); 
      return this; 
  }; 
}(jQuery));

즉시 호출 함수표현을 사용하는 또 다른 주된 목적은 플러그인 자신의 private변수를 가질 수 있다는 것입니다.

(function($) { 
	var shade = "#556b2f"; 
    $.fn.greenify = function() { 
    	this.css("color", shade); 
        return this;
     }; 
 }(jQuery));

 

5. 플러그인 풋프린터(Footprint)를 최소화

다음과 같이 하나의 플러그인을 위해서 여러개의 함수 이름을 사용하는 것은 다른 플러그인이 이름을 사용할 기회를 줄이므로 파라미터를 사용해서 하나의 이름으로 사용하는 것이 좋습니다.

(function($) { 
	$.fn.openPopup = function() { 
    // 팝업을 여는 코드. 
    }; 
    $.fn.closePopup = function() { 
    // 팝업을 닫는 코드. 
    }; 
 }(jQuery));

파라미터를 사용하여 하나의 이름을 사용합니다.

(function($) { 
	$.fn.popup = function(action) { 
    	if(action === "open") { 
        	// 팝업을 여는 코드. 
          } 
        if(action === "close") { 
        	// 팝업을 닫는 코드. 
         } 
     }; 
  }(jQuery));

 

6. each() 메서드의 사용

일반적인 jQuery 객체는 여러개의 요소의 참조를 포함하며 jQuery 객체를 종종 컬렉션이라 부른다. 여러개의 요소가 선택되었을 경우 각 요소에 대해 작업을 수행하는데 .each() 메소드를 사용합니다.

$.fn.myNewPlugin = function() { 
	return this.each(function() { 
    	// 각 요소에 대해 작업을 합니다. 
     });
 };

 

7. 옵션을 받아서 사용하기

플러그인을 커스터마이즈 할 수 있도록 옵션을 받아서 사용하도록 합니다.

(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> 요소에 href 속성값을 같이 출력되게 하는 예제 입니다.

(function($) { 
	$.fn.showLinkLocation = function() { 
    	this.filter("a").each(function() { 
        	var link = $(this); link.append(" (" + link.attr("href") + ")"); }); 
            return this; 
     }; 
 }(jQuery)); 
      
 // 플러그인 사용 예: 
 $( "a" ).showLinkLocation();


러그인 적용 결과 입니다.

<!-- 플러그인 적용 전의 모습 입니다: --> 
<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));

 고급 플러그인 개념

1. 기본 플러그인 설정에 대한 액세스

옵션 변경 사용법

// Plugin definition.
$.fn.hilight = function( options ) {
 
    // Extend our default options with those provided.
    // Note that the first argument to extend is an empty
    // object – this is to keep from overriding our "defaults" object.
    var opts = $.extend( {}, $.fn.hilight.defaults, options );
 
    // Our plugin implementation code goes here.
 
};
 
// Plugin defaults – added as a property on our plugin function.
$.fn.hilight.defaults = {
    foreground: "red",
    background: "yellow"
};

// This needs only be called once and does not
// have to be called from within a "ready" block
$.fn.hilight.defaults.foreground = "blue";

$( "#myDiv" ).hilight();

// Override plugin default foreground color.
$.fn.hilight.defaults.foreground = "blue";
 
// ...
 
// Invoke plugin using new defaults.
$( ".hilightDiv" ).hilight();
 
// ...
 
// Override default by passing options to plugin method.
$( "#green" ).hilight({
    foreground: "green"
});

2. 보조 Functions에 대한 액세스

function을 재정의할 수 있도록 'format'함수를 실제로 노출시킨다. 이 기술을 사용하면 다른 사용자가 플러그인에 대한 정의 재정의를 할 수 있다.

// Plugin definition.
$.fn.hilight = function( options ) {
 
    // Iterate and reformat each matched element.
    return this.each(function() {
 
        var elem = $( this );
 
        // ...
 
        var markup = elem.html();
 
        // Call our format function.
        markup = $.fn.hilight.format( markup );
 
        elem.html( markup );
 
    });
 
};
 
// Define our format function.
$.fn.hilight.format = function( txt ) {
    return "<strong>" + txt + "</strong>";
};

3. Private Function 

debug는 외부에서 접근할 수 없는 함수이다.

// Create closure.
(function( $ ) {
 
    // Plugin definition.
    $.fn.hilight = function( options ) {
        debug( this );
        // ...
    };
 
    // Private function for debugging.
    function debug( obj ) {
        if ( window.console && window.console.log ) {
            window.console.log( "hilight selection count: " + obj.length );
        }
    };
 
    // ...
 
// End of closure.
 
})( jQuery );

4. 플러그의 옵션수가 중요한 것이 아니라 어떤 옵션을 가지고 있는가가 중요

jQuery.fn.superGallery = function( options ) {
 
    // Bob's default settings:
    var defaults = {
        textColor: "#000",
        backgroundColor: "#fff",
        fontSize: "1em",
        delay: "quite long",
        getTextFromTitle: true,
        getTextFromRel: false,
        getTextFromAlt: false,
        animateWidth: true,
        animateOpacity: true,
        animateHeight: true,
        animationDuration: 500,
        clickImgToGoToNext: true,
        clickImgToGoToLast: false,
        nextButtonText: "next",
        previousButtonText: "previous",
        nextButtonTextColor: "red",
        previousButtonTextColor: "red"
    };
 
    var settings = $.extend( {}, defaults, options );
 
    return this.each(function() {
        // Plugin code would go here...
    });
 
};

5. 플러그인 관련 구문을 만들지 마라

지연 시간을 정의하기 위한 코드 12줄은 좀 과하다고 생각하지 않으세요? 이 옵션을 구성하는 더 좋은 방법은 플러그인 사용자가 시간(밀리초)을 숫자로 지정하여 옵션 처리를 수행할 필요가 없도록 하는 것이다.

var delayDuration = 0;
 
switch ( settings.delay ) {
 
    case "very short":
        delayDuration = 100;
        break;
 
    case "quite short":
        delayDuration = 200;
        break;
 
    case "quite long":
        delayDuration = 300;
        break;
 
    case "very long":
        delayDuration = 400;
        break;
 
    default:
        delayDuration = 200;
 
}

6. 요소의 완전한 제어 권한 부여

A bad implementation

// Plugin code
$( "<div class='gallery-wrapper' />" ).appendTo( "body" );
 
$( ".gallery-wrapper" ).append( "..." );

A better implementation

// Retain an internal reference:
var wrapper = $( "<div />" )
    .attr( settings.wrapperAttrs )
    .appendTo( settings.container );
 
// Easy to reference later...
wrapper.append( "..." );

6. 깊은 복사

var defaults = {
    wrapperAttrs : {
        class: "gallery-wrapper"
    },
    // ... rest of settings ...
};
 
// We can use the extend method to merge options/settings as usual:
// But with the added first parameter of TRUE to signify a DEEP COPY:
var settings = $.extend( true, {}, defaults, options );

 사용자 정의 css styles 쉽게 가져오기

var defaults = {
    wrapperCSS: {},
    // ... rest of settings ...
};
 
// Later on in the plugin where we define the wrapper:
var wrapper = $( "<div />" )
    .attr( settings.wrapperAttrs )
    .css( settings.wrapperCSS ) // ** Set CSS!
    .appendTo( settings.container );

7. 콜백기능 제공

콜백이란 무엇인가? – 콜백(callback)은 본질적으로 나중에 호출할 함수로서 일반적으로 이벤트에 의해 트리거된다. 

var defaults = {
 
    // We define an empty anonymous function so that
    // we don't need to check its existence before calling it.
    onImageShow : function() {},
 
    // ... rest of settings ...
 
};
 
// Later on in the plugin:
 
nextButton.on( "click", showNextImage );
 
function showNextImage() {
 
    // Returns reference to the next image node
    var image = getNextImage();
 
    // Stuff to show the image here...
 
    // Here's the callback:
    settings.onImageShow.call( image );
}
$( "ul.imgs li" ).superGallery({
    onImageShow: function() {
        $( this ).after( "<span>" + $( this ).attr( "longdesc" ) + "</span>" );
    },
 
    // ... other options ...
});

 

 

1.유연성: 플러그인이 처리할 수 있는 상황은 몇가지 안가?

2. 크기 : 플러그인의 크기가 해당 기능 수준에 합당한가? 기본적인 툴팁인데 20k라면?

3. 성능: 플러그인이 어떤 방식 으로든 옵션을 많이 처리합니까? 이것이 속도에 영향을 줍니까? 최종 사용자에게 오버 헤드가 발생합니까?

 

'Javascript > jQuery' 카테고리의 다른 글

Function.prototype.bind()  (0) 2020.06.13
Function.prototype.apply()  (0) 2020.06.13
Function.prototype.call()  (0) 2020.06.13
jQuery.fn.extend()  (0) 2020.06.13
jQuery.extend()  (0) 2020.06.13