메소드를 사용하여 jQuery 플러그인을 작성하는 방법은 무엇입니까?


191

호출하는 객체에 추가 기능 / 메소드를 제공하는 jQuery 플러그인을 작성하려고합니다. 온라인에서 읽은 모든 자습서 (지난 2 시간 동안 탐색 했음)에는 대부분 옵션을 추가하는 방법이 포함되지만 추가 기능은 포함되지 않습니다.

내가하고 싶은 일은 다음과 같습니다.

// 해당 div에 대한 플러그인을 호출하여 div를 메시지 컨테이너로 포맷

$("#mydiv").messagePlugin();
$("#mydiv").messagePlugin().saySomething("hello");

또는 그 라인을 따라 뭔가. 플러그인을 호출 한 다음 해당 플러그인과 관련된 함수를 호출합니다. 나는 이것을 할 수있는 방법을 찾지 못하는 것 같으며 많은 플러그인이 전에 그것을하는 것을 보았습니다.

플러그인에 대해 지금까지 가지고있는 내용은 다음과 같습니다.

jQuery.fn.messagePlugin = function() {
  return this.each(function(){
    alert(this);
  });

  //i tried to do this, but it does not seem to work
  jQuery.fn.messagePlugin.saySomething = function(message){
    $(this).html(message);
  }
};

어떻게 그런 걸 얻을 수 있습니까?

감사합니다!


2013 년 11 월 18 일 업데이트 : Hari의 다음 의견과 의견에 대한 정답을 변경했습니다.

답변:


310

jQuery 플러그인 작성 페이지 ( http://docs.jquery.com/Plugins/Authoring ) 에 따르면 jQuery 및 jQuery.fn 네임 스페이스를 숨기지 않는 것이 가장 좋습니다. 그들은이 방법을 제안합니다 :

(function( $ ){

    var methods = {
        init : function(options) {

        },
        show : function( ) {    },// IS
        hide : function( ) {  },// GOOD
        update : function( content ) {  }// !!!
    };

    $.fn.tooltip = function(methodOrOptions) {
        if ( methods[methodOrOptions] ) {
            return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {
            // Default to "init"
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  methodOrOptions + ' does not exist on jQuery.tooltip' );
        }    
    };


})( jQuery );

기본적으로 함수를 배열 (랩핑 함수 범위)에 저장하고 전달 된 매개 변수가 문자열 인 경우 항목을 확인하고 매개 변수가 오브젝트 (또는 널) 인 경우 기본 메소드 ( "init")로 되돌립니다.

그런 다음 메소드를 호출 할 수 있습니다.

$('div').tooltip(); // calls the init method
$('div').tooltip({  // calls the init method
  foo : 'bar'
});
$('div').tooltip('hide'); // calls the hide method
$('div').tooltip('update', 'This is the new tooltip content!'); // calls the update method

Javascripts "arguments"변수는 전달 된 모든 인수의 배열이므로 임의의 길이의 함수 매개 변수와 함께 작동합니다.


2
이것이 내가 사용하는 방법입니다. $ .fn.tooltip ( 'methodname', params);를 통해 메소드를 정적으로 호출 할 수도 있습니다.
Rake36

1
매우 편리한 아키텍처. 또한 init 메소드를 호출하기 전에이 행을 추가했습니다. this.data('tooltip', $.extend(true, {}, $.fn.tooltip.defaults, methodOrOptions));이제 초기화 후 원하는 때마다 옵션에 액세스 할 수 있습니다.
ivkremer

16
- 상기 제 1 누가 나 같은 어떤 들어 "여기서 인수 변수에서 왔는가" developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... 영원히 JS를 사용하고 그 몰랐어요 -. 매일 새로운 것을 배웁니다!
streetlogics

2
@ DiH, 나는 이것에 당신과 함께 있습니다. 이 방법은 훌륭해 보이지만 이외의 다른 곳에서는 전역 설정에 액세스 할 수 없습니다 init.
Stephen Collins

4
이 기술에는 큰 문제가 있습니다! 생각하고있는 것처럼 선택기의 모든 요소에 대해 새 인스턴스를 만들지 않고 선택기 자체에 연결된 단일 인스턴스 만 만듭니다. 보기 내 대답 솔루션을합니다.
Kevin Jurkowski 1

56

추가 방법으로 플러그인을 만드는 데 사용한 패턴은 다음과 같습니다. 당신은 그것을 다음과 같이 사용할 것입니다 :

$('selector').myplugin( { key: 'value' } );

또는 메소드를 직접 호출하려면

$('selector').myplugin( 'mymethod1', 'argument' );

예:

;(function($) {

    $.fn.extend({
        myplugin: function(options,arg) {
            if (options && typeof(options) == 'object') {
                options = $.extend( {}, $.myplugin.defaults, options );
            }

            // this creates a plugin for each element in
            // the selector or runs the function once per
            // selector.  To have it do so for just the
            // first element (once), return false after
            // creating the plugin to stop the each iteration 
            this.each(function() {
                new $.myplugin(this, options, arg );
            });
            return;
        }
    });

    $.myplugin = function( elem, options, arg ) {

        if (options && typeof(options) == 'string') {
           if (options == 'mymethod1') {
               myplugin_method1( arg );
           }
           else if (options == 'mymethod2') {
               myplugin_method2( arg );
           }
           return;
        }

        ...normal plugin actions...

        function myplugin_method1(arg)
        {
            ...do method1 with this and arg
        }

        function myplugin_method2(arg)
        {
            ...do method2 with this and arg
        }

    };

    $.myplugin.defaults = {
       ...
    };

})(jQuery);

9
jquery-ui와 동일한 패턴, 나는 모든 마술 문자열을 좋아하지 않지만 다른 방법이 있습니다!
redsquare

8
이것은 비표준 방식으로 일하는 것 같습니다. 연쇄 함수와 같이 이것보다 간단한 것이 있습니까? 감사합니다!
유발 카르미

2
@yuval-일반적으로 jQuery 플러그인은 플러그인 자체가 아니라 jQuery 또는 값을 반환합니다. 플러그인을 호출하려고 할 때 메소드의 이름이 플러그인에 인수로 전달되는 이유입니다. 여러 개의 인수를 전달할 수 있지만 함수와 인수 구문 분석을 조정해야합니다. 당신이 보여준 것처럼 익명의 객체로 설정하는 것이 가장 좋습니다.
tvanfosson

1
;첫 번째 줄 의 의미는 무엇입니까 ? :) 나에게 설명해주십시오
GusDeCooL

4
@GusDeCooL은 함수 정의가 형식이 잘못된 다른 자바 스크립트에 대한 인수로 해석되지 않도록 새 명령문을 시작하도록합니다 (즉, 초기 파링은 함수 호출 연산자로 사용되지 않음). 참조 stackoverflow.com/questions/7365172/...
tvanfosson

35

이 방법은 어떻습니까?

jQuery.fn.messagePlugin = function(){
    var selectedObjects = this;
    return {
             saySomething : function(message){
                              $(selectedObjects).each(function(){
                                $(this).html(message);
                              });
                              return selectedObjects; // Preserve the jQuery chainability 
                            },
             anotherAction : function(){
                               //...
                               return selectedObjects;
                             }
           };
}
// Usage:
$('p').messagePlugin().saySomething('I am a Paragraph').css('color', 'red');

선택한 객체는 messagePlugin 클로저에 저장되며 해당 함수는 플러그인과 관련된 함수가 포함 된 객체를 반환합니다. 각 함수에서 현재 선택한 객체에 대해 원하는 작업을 수행 할 수 있습니다.

여기 에서 코드를 테스트하고 재생할 수 있습니다 .

편집 : jQuery 체인 기능을 유지하기 위해 코드가 업데이트되었습니다.


1
이것이 어떻게 보이는지 이해하는 데 약간의 어려움이 있습니다. 처음 실행될 때 실행해야하는 코드가 있다고 가정하면 먼저 코드에서 초기화해야합니다. $ ( 'p'). messagePlugin (); 그런 다음 코드에서 나중에이 $ ( 'p'). messagePlugin (). saySomething ( 'something')과 같은 saySomething 함수를 호출하고 싶습니다. 플러그인을 다시 초기화하지 않고 함수를 호출하지 않습니까? 인클로저와 옵션의 경우 어떤 모습입니까? 대단히 감사합니다. -yuval
Yuval Karmi

1
그래도 jQuery의 체인 성 패러다임을 깨뜨립니다.
tvanfosson

아마도 이것이 가장 좋은 대답
Dragouf

3
messagePlugin ()을 호출 할 때마다이 두 함수를 가진 새로운 객체가 생성됩니다.
w00t

4
이 접근 방식의 주요 문제 $('p').messagePlugin()는 반환하는 두 함수 중 하나를 호출하지 않으면 체인 기능을 유지할 수 없다는 것입니다.
Joshua Bambrick 2016 년

18

현재 선택된 답변의 문제점은 실제로 생각하는 것처럼 선택기의 모든 요소에 대해 사용자 정의 플러그인의 새 인스턴스를 실제로 생성하지 않고 실제로 단일 인스턴스 만 생성하고 전달한다는 것입니다 선택기 자체가 범위입니다.

보기 이 바이올린을 더 깊은 설명.

대신 jQuery.each를 사용하여 선택기를 반복하고 선택기의 모든 요소에 대해 사용자 정의 플러그인의 새 인스턴스를 인스턴스화해야합니다.

방법은 다음과 같습니다.

(function($) {

    var CustomPlugin = function($el, options) {

        this._defaults = {
            randomizer: Math.random()
        };

        this._options = $.extend(true, {}, this._defaults, options);

        this.options = function(options) {
            return (options) ?
                $.extend(true, this._options, options) :
                this._options;
        };

        this.move = function() {
            $el.css('margin-left', this._options.randomizer * 100);
        };

    };

    $.fn.customPlugin = function(methodOrOptions) {

        var method = (typeof methodOrOptions === 'string') ? methodOrOptions : undefined;

        if (method) {
            var customPlugins = [];

            function getCustomPlugin() {
                var $el          = $(this);
                var customPlugin = $el.data('customPlugin');

                customPlugins.push(customPlugin);
            }

            this.each(getCustomPlugin);

            var args    = (arguments.length > 1) ? Array.prototype.slice.call(arguments, 1) : undefined;
            var results = [];

            function applyMethod(index) {
                var customPlugin = customPlugins[index];

                if (!customPlugin) {
                    console.warn('$.customPlugin not instantiated yet');
                    console.info(this);
                    results.push(undefined);
                    return;
                }

                if (typeof customPlugin[method] === 'function') {
                    var result = customPlugin[method].apply(customPlugin, args);
                    results.push(result);
                } else {
                    console.warn('Method \'' + method + '\' not defined in $.customPlugin');
                }
            }

            this.each(applyMethod);

            return (results.length > 1) ? results : results[0];
        } else {
            var options = (typeof methodOrOptions === 'object') ? methodOrOptions : undefined;

            function init() {
                var $el          = $(this);
                var customPlugin = new CustomPlugin($el, options);

                $el.data('customPlugin', customPlugin);
            }

            return this.each(init);
        }

    };

})(jQuery);

그리고 일하는 바이올린 .

첫 번째 바이올린에서 모든 div가 항상 정확히 같은 수의 픽셀로 오른쪽으로 이동하는 방법을 알 수 있습니다. 선택기의 모든 요소에 대해 하나의 옵션 오브젝트 만 존재하기 때문 입니다.

위에서 설명한 기술을 사용하면 두 번째 바이올린에서 각 div가 정렬되지 않고 무작위로 이동합니다 (랜덤 라이저의 첫 번째 div는 항상 89 행에서 1로 설정되므로 제외). 이제 선택기의 모든 요소에 대해 새 사용자 정의 플러그인 인스턴스를 올바르게 인스턴스화하고 있기 때문입니다. 모든 요소에는 자체 옵션 객체가 있으며 선택기에 저장되지 않고 사용자 정의 플러그인 자체에 저장됩니다.

즉, 새 jQuery 선택기에서 DOM의 특정 요소로 인스턴스화 된 사용자 정의 플러그인의 메소드에 액세스 할 수 있으며 첫 번째 바이올린에서와 같이 캐시하지 않아도됩니다.

예를 들어, 이것은 두 번째 바이올린의 기술을 사용하여 모든 옵션 객체의 배열을 반환합니다. 처음에는 undefined를 반환합니다.

$('div').customPlugin();
$('div').customPlugin('options'); // would return an array of all options objects

이것은 첫 번째 바이올린에서 옵션 객체에 액세스 해야하는 방법이며 배열이 아닌 단일 객체 만 반환합니다.

var divs = $('div').customPlugin();
divs.customPlugin('options'); // would return a single options object

$('div').customPlugin('options');
// would return undefined, since it's not a cached selector

현재 선택된 답변이 아닌 위의 기술을 사용하는 것이 좋습니다.


고마워, 이것은 특히 나에게 .data () 메소드를 소개하는 데 도움이되었습니다. 매우 편리합니다. 또한 익명 메소드를 사용하여 일부 코드를 단순화 할 수도 있습니다.
dalemac

이 방법으로 jQuery 연결성이 작동하지 않습니다 ... $('.my-elements').find('.first-input').customPlugin('update'‌​, 'first value').end().find('.second-input').customPlugin('update', 'second value'); returns Cannot read property 'end' of undefined . jsfiddle.net/h8v1k2pL
Alex G

16

jQuery는 Widget Factory 의 도입으로 이것을 훨씬 쉽게 만들었습니다 .

예:

$.widget( "myNamespace.myPlugin", {

    options: {
        // Default options
    },

    _create: function() {
        // Initialization logic here
    },

    // Create a public method.
    myPublicMethod: function( argument ) {
        // ...
    },

    // Create a private method.
    _myPrivateMethod: function( argument ) {
        // ...
    }

});

초기화 :

$('#my-element').myPlugin();
$('#my-element').myPlugin( {defaultValue:10} );

메소드 호출 :

$('#my-element').myPlugin('myPublicMethod', 20);

(이것은 jQuery UI 라이브러리가 구축되는 방식입니다.)


@ daniel.sedlacek a) "매우 나쁜 아키텍처"-jQuery의 표준 위젯 아키텍처입니다. b) "컴파일시 무결성 검사"-JavaScript는 동적 언어입니다. c) "TypeScript"-wha?
Yarin

A) 그건 군중에 호소하는 오류, b)는 모든 더 나은 JS IDE는 코드 완성 또는 linting, C)를 구글이
daniel.sedlacek

세드 락 씨, 그건 망상입니다.
mystrdat

문서 별 : 이 시스템을 위젯 팩토리라고하며 jQuery UI 1.8의 일부로 jQuery.widget으로 노출됩니다. 그러나 jQuery UI와 독립적으로 사용할 수 있습니다. jQuery UI 없이 $ .widget을 어떻게 사용 합니까?
Airn5475

13

더 간단한 방법은 중첩 함수를 사용하는 것입니다. 그런 다음 객체 지향 방식으로 연결할 수 있습니다. 예:

jQuery.fn.MyPlugin = function()
{
  var _this = this;
  var a = 1;

  jQuery.fn.MyPlugin.DoSomething = function()
  {
    var b = a;
    var c = 2;

    jQuery.fn.MyPlugin.DoSomething.DoEvenMore = function()
    {
      var d = a;
      var e = c;
      var f = 3;
      return _this;
    };

    return _this;
  };

  return this;
};

그것을 부르는 방법은 다음과 같습니다.

var pluginContainer = $("#divSomeContainer");
pluginContainer.MyPlugin();
pluginContainer.MyPlugin.DoSomething();
pluginContainer.MyPlugin.DoSomething.DoEvenMore();

그래도 조심하십시오. 중첩 함수는 생성 될 때까지 호출 할 수 없습니다. 그래서 당신은 이것을 할 수 없습니다 :

var pluginContainer = $("#divSomeContainer");
pluginContainer.MyPlugin();
pluginContainer.MyPlugin.DoSomething.DoEvenMore();
pluginContainer.MyPlugin.DoSomething();

DoEvenMore 함수를 작성하는 데 필요한 DoSomething 함수가 아직 실행되지 않았으므로 DoEvenMore 함수는 존재하지 않습니다. 대부분의 jQuery 플러그인의 경우 실제로 여기에 표시된 것과 같이 한 수준의 중첩 함수 만 있고 두 가지가 아닙니다.
중첩 함수를 생성 할 때 부모 함수의 다른 코드가 실행되기 전에 부모 함수의 시작 부분에서 이러한 함수를 정의해야합니다.

마지막으로 "this"멤버는 "_this"라는 변수에 저장됩니다. 중첩 함수의 경우 호출 클라이언트의 인스턴스에 대한 참조가 필요한 경우 "_this"를 반환해야합니다. jQuery 인스턴스가 아닌 함수에 대한 참조를 리턴하므로 중첩 함수에서 "this"만 리턴 할 수 없습니다. jQuery 참조를 리턴하면 리턴시 고유 jQuery 메소드를 연결할 수 있습니다.


2
이것은 훌륭합니다-왜 jQuery가 .plugin ( 'method') 패턴 에서처럼 이름으로 메소드를 호출하는 것을 선호하는지 궁금합니다.
w00t

6
작동하지 않습니다. 두 개의 다른 컨테이너에서 플러그인을 호출하면 내부 변수가 재정의됩니다 (즉, _this)
mbrochh

실패 : pluginContainer.MyPlugin.DoEvenMore (). DoSomething ();
Paul Swetz

9

jQuery Plugin Boilerplate 에서 얻었습니다.

jQuery Plugin Boilerplate 에도 설명되어 있습니다.

// jQuery Plugin Boilerplate
// A boilerplate for jumpstarting jQuery plugins development
// version 1.1, May 14th, 2011
// by Stefan Gabos

// remember to change every instance of "pluginName" to the name of your plugin!
(function($) {

    // here we go!
    $.pluginName = function(element, options) {

    // plugin's default options
    // this is private property and is accessible only from inside the plugin
    var defaults = {

        foo: 'bar',

        // if your plugin is event-driven, you may provide callback capabilities
        // for its events. execute these functions before or after events of your
        // plugin, so that users may customize those particular events without
        // changing the plugin's code
        onFoo: function() {}

    }

    // to avoid confusions, use "plugin" to reference the
    // current instance of the object
    var plugin = this;

    // this will hold the merged default, and user-provided options
    // plugin's properties will be available through this object like:
    // plugin.settings.propertyName from inside the plugin or
    // element.data('pluginName').settings.propertyName from outside the plugin,
    // where "element" is the element the plugin is attached to;
    plugin.settings = {}

    var $element = $(element), // reference to the jQuery version of DOM element
    element = element; // reference to the actual DOM element

    // the "constructor" method that gets called when the object is created
    plugin.init = function() {

    // the plugin's final properties are the merged default and
    // user-provided options (if any)
    plugin.settings = $.extend({}, defaults, options);

    // code goes here

   }

   // public methods
   // these methods can be called like:
   // plugin.methodName(arg1, arg2, ... argn) from inside the plugin or
   // element.data('pluginName').publicMethod(arg1, arg2, ... argn) from outside
   // the plugin, where "element" is the element the plugin is attached to;

   // a public method. for demonstration purposes only - remove it!
   plugin.foo_public_method = function() {

   // code goes here

    }

     // private methods
     // these methods can be called only from inside the plugin like:
     // methodName(arg1, arg2, ... argn)

     // a private method. for demonstration purposes only - remove it!
     var foo_private_method = function() {

        // code goes here

     }

     // fire up the plugin!
     // call the "constructor" method
     plugin.init();

     }

     // add the plugin to the jQuery.fn object
     $.fn.pluginName = function(options) {

        // iterate through the DOM elements we are attaching the plugin to
        return this.each(function() {

          // if plugin has not already been attached to the element
          if (undefined == $(this).data('pluginName')) {

              // create a new instance of the plugin
              // pass the DOM element and the user-provided options as arguments
              var plugin = new $.pluginName(this, options);

              // in the jQuery version of the element
              // store a reference to the plugin object
              // you can later access the plugin and its methods and properties like
              // element.data('pluginName').publicMethod(arg1, arg2, ... argn) or
              // element.data('pluginName').settings.propertyName
              $(this).data('pluginName', plugin);

           }

        });

    }

})(jQuery);

당신의 방법은 jQuery 연결을 끊는다 : jsfiddle.net/h8v1k2pL/1을$('.first-input').data('pluginName').publicMethod('new value').css('color', red); 반환Cannot read property 'css' of undefined
Alex G

@AlexG는이 예제를 제공 하므로이 예제 return $element에서 추가 하면 plugin.foo_public_method = function() {/* Your Code */ return $element;}@Salim으로 변경 하여 도움을 주셔서 감사합니다 ... github.com/AndreaLombardo/BootSideMenu/pull/34
CrandellWS

6

너무 늦었지만 언젠가 누군가를 도울 수 있습니다.

나는 몇 가지 방법으로 jQuery 플러그인을 만드는 것과 같은 상황에 있었고, 기사와 타이어를 읽은 후 jQuery 플러그인 상용구를 만들었습니다 ( https://github.com/acanimal/jQuery-Plugin-Boilerplate ).

또한 태그를 관리하는 플러그인 ( https://github.com/acanimal/tagger.js )을 사용하여 jQuery 플러그인 ( http : // acuriousanimal)을 단계별로 설명하는 두 개의 블로그 게시물을 작성 했습니다. com / blog / 2013 / 01 / 15 / things-i-learned-creating-a-jquery-plugin-part-i / ).


어쩌면 초보자로 jQuery 플러그인을 만드는 것에 대해 아직까지 올린 최고의 게시물-감사합니다.)
Dex Dave

5

넌 할 수있어:

(function($) {
  var YourPlugin = function(element, option) {
    var defaults = {
      //default value
    }

    this.option = $.extend({}, defaults, option);
    this.$element = $(element);
    this.init();
  }

  YourPlugin.prototype = {
    init: function() { },
    show: function() { },
    //another functions
  }

  $.fn.yourPlugin = function(option) {
    var arg = arguments,
        options = typeof option == 'object' && option;;
    return this.each(function() {
      var $this = $(this),
          data = $this.data('yourPlugin');

      if (!data) $this.data('yourPlugin', (data = new YourPlugin(this, options)));
      if (typeof option === 'string') {
        if (arg.length > 1) {
          data[option].apply(data, Array.prototype.slice.call(arg, 1));
        } else {
          data[option]();
        }
      }
    });
  };
});

이런 식으로 플러그인 객체는 요소에 데이터 값으로 저장됩니다.

//Initialization without option
$('#myId').yourPlugin();

//Initialization with option
$('#myId').yourPlugin({
  // your option
});

// call show method
$('#myId').yourPlugin('show');

3

트리거 사용은 어떻습니까? 누구든지 그것들을 사용하는 단점을 알고 있습니까? 장점은 모든 내부 변수가 트리거를 통해 액세스 할 수 있으며 코드가 매우 간단하다는 것입니다.

jsfiddle을 참조하십시오 .

사용법 예

<div id="mydiv">This is the message container...</div>

<script>
    var mp = $("#mydiv").messagePlugin();

    // the plugin returns the element it is called on
    mp.trigger("messagePlugin.saySomething", "hello");

    // so defining the mp variable is not needed...
    $("#mydiv").trigger("messagePlugin.repeatLastMessage");
</script>

플러그인

jQuery.fn.messagePlugin = function() {

    return this.each(function() {

        var lastmessage,
            $this = $(this);

        $this.on('messagePlugin.saySomething', function(e, message) {
            lastmessage = message;
            saySomething(message);
        });

        $this.on('messagePlugin.repeatLastMessage', function(e) {
            repeatLastMessage();
        });

        function saySomething(message) {
            $this.html("<p>" + message + "</p>");
        }

        function repeatLastMessage() {
            $this.append('<p>Last message was: ' + lastmessage + '</p>');
        }

    });

}

1
cf. 당신의 의견. 내가 여기서 볼 수있는 유일한 문제는 아마도 이벤트 시스템의 오용일 것입니다. 함수를 호출하기 위해 순전히 이벤트를 사용하는 것은 비정형입니다. 그것은 잔인한 것처럼 보이고 쉽게 깨질 수 있습니다. 일반적으로 이벤트를 게시-구독 방식으로 사용합니다. 예를 들어 함수는 "A"조건이 발생했음을 게시합니다. "A"에 관심이있는 다른 엔티티는 "A"가 발생했다는 메시지를 듣고 무언가를합니다. 대신 "command"를 푸시로 사용하는 것 같지만 리스너가 하나만 있다고 가정합니다. 리스너를 추가하여 (다른 사용자) 시맨틱이 손상되지 않도록주의하고 싶습니다.
tvanfosson

@tvanfosson 귀하의 의견에 감사드립니다. 나는 일반적인 기술이 아니며 누군가 실수로 이벤트 리스너를 추가하면 문제가 발생할 수 있지만 플러그인 이름을 따서 명명하면 매우 가능성이 낮습니다. 성능 관련 문제에 대해서는 잘 모르지만 코드 자체는 다른 솔루션보다 훨씬 간단 해 보이지만 누락 될 수 있습니다.
István Ujj-Mészáros

3

여기에 인수가있는 간단한 플러그인을 만드는 단계를 제안하고 싶습니다.

(function($) {
  $.fn.myFirstPlugin = function(options) {
    // Default params
    var params = $.extend({
      text     : 'Default Title',
      fontsize : 10,
    }, options);
    return $(this).text(params.text);
  }
}(jQuery));

$('.cls-title').myFirstPlugin({ text : 'Argument Title' });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 class="cls-title"></h1>

여기에서 함수 라는 기본 개체를 추가 params하고 옵션을 사용하여 옵션의 기본값을 설정했습니다 extend. 따라서 빈 인수를 전달하면 기본값이 설정되고 그렇지 않으면 설정됩니다.

더 읽기 : JQuery 플러그인을 만드는 방법


안녕하세요 Gopal Joshi, 다음 레벨의 jquery 플러그인 작성을 제공하십시오. 우리는 당신의 필요한 답변을 기대합니다.
Sakthi Karthik

안녕하세요 @SakthiKarthik, 오프 cource 나는 내 블로그에 곧 새로운 자습서를 게시합니다
Gopal Joshi

1
안녕하세요 @SakthiKarthik는, 당신은 다음 수준에 새로운 기사를 참조 할 수 있습니다 JQuery와 플러그인 여기 sgeek.org/...
고팔 조시

2

이거 한번 해봐:

$.fn.extend({
"calendar":function(){
    console.log(this);
    var methods = {
            "add":function(){console.log("add"); return this;},
            "init":function(){console.log("init"); return this;},
            "sample":function(){console.log("sample"); return this;}
    };

    methods.init(); // you can call any method inside
    return methods;
}}); 
$.fn.calendar() // caller or 
$.fn.calendar().sample().add().sample() ......; // call methods

1

여기 내 베어 본 버전이 있습니다. 이전에 게시 한 것과 유사하게 다음과 같이 전화하십시오.

$('#myDiv').MessagePlugin({ yourSettings: 'here' })
           .MessagePlugin('saySomething','Hello World!');

또는 인스턴스에 직접 액세스 @ plugin_MessagePlugin

$elem = $('#myDiv').MessagePlugin();
var instance = $elem.data('plugin_MessagePlugin');
instance.saySomething('Hello World!');

MessagePlugin.js

;(function($){

    function MessagePlugin(element,settings){ // The Plugin
        this.$elem = element;
        this._settings = settings;
        this.settings = $.extend(this._default,settings);
    }

    MessagePlugin.prototype = { // The Plugin prototype
        _default: {
            message: 'Generic message'
        },
        initialize: function(){},
        saySomething: function(message){
            message = message || this._default.message;
            return this.$elem.html(message);
        }
    };

    $.fn.MessagePlugin = function(settings){ // The Plugin call

        var instance = this.data('plugin_MessagePlugin'); // Get instance

        if(instance===undefined){ // Do instantiate if undefined
            settings = settings || {};
            this.data('plugin_MessagePlugin',new MessagePlugin(this,settings));
            return this;
        }

        if($.isFunction(MessagePlugin.prototype[settings])){ // Call method if argument is name of method
            var args = Array.prototype.slice.call(arguments); // Get the arguments as Array
            args.shift(); // Remove first argument (name of method)
            return MessagePlugin.prototype[settings].apply(instance, args); // Call the method
        }

        // Do error handling

        return this;
    }

})(jQuery);

1

다음 플러그인 구조는 jQuery- data()메소드 를 사용하여 내부 플러그인 메소드 / 설정에 대한 공개 인터페이스를 제공 합니다 ( jQuery 체인 기능유지함 ).

(function($, window, undefined) { 
  const defaults = {
    elementId   : null,
    shape       : "square",
    color       : "aqua",
    borderWidth : "10px",
    borderColor : "DarkGray"
  };

  $.fn.myPlugin = function(options) {
    // settings, e.g.:  
    var settings = $.extend({}, defaults, options);

    // private methods, e.g.:
    var setBorder = function(color, width) {        
      settings.borderColor = color;
      settings.borderWidth = width;          
      drawShape();
    };

    var drawShape = function() {         
      $('#' + settings.elementId).attr('class', settings.shape + " " + "center"); 
      $('#' + settings.elementId).css({
        'background-color': settings.color,
        'border': settings.borderWidth + ' solid ' + settings.borderColor      
      });
      $('#' + settings.elementId).html(settings.color + " " + settings.shape);            
    };

    return this.each(function() { // jQuery chainability     
      // set stuff on ini, e.g.:
      settings.elementId = $(this).attr('id'); 
      drawShape();

      // PUBLIC INTERFACE 
      // gives us stuff like: 
      //
      //    $("#...").data('myPlugin').myPublicPluginMethod();
      //
      var myPlugin = {
        element: $(this),
        // access private plugin methods, e.g.: 
        setBorder: function(color, width) {        
          setBorder(color, width);
          return this.element; // To ensure jQuery chainability 
        },
        // access plugin settings, e.g.: 
        color: function() {
          return settings.color;
        },        
        // access setting "shape" 
        shape: function() {
          return settings.shape;
        },     
        // inspect settings 
        inspectSettings: function() {
          msg = "inspecting settings for element '" + settings.elementId + "':";   
          msg += "\n--- shape: '" + settings.shape + "'";
          msg += "\n--- color: '" + settings.color + "'";
          msg += "\n--- border: '" + settings.borderWidth + ' solid ' + settings.borderColor + "'";
          return msg;
        },               
        // do stuff on element, e.g.:  
        change: function(shape, color) {        
          settings.shape = shape;
          settings.color = color;
          drawShape();   
          return this.element; // To ensure jQuery chainability 
        }
      };
      $(this).data("myPlugin", myPlugin);
    }); // return this.each 
  }; // myPlugin
}(jQuery));

이제 내부 플러그인 메소드를 호출하여 다음 구문을 사용하여 플러그인 데이터 또는 관련 요소에 액세스하거나 수정할 수 있습니다.

$("#...").data('myPlugin').myPublicPluginMethod(); 

myPublicPluginMethod()jQuery-chainability 구현에서 현재 요소 (this)를 반환하는 한 다음과 같이 작동합니다.

$("#...").data('myPlugin').myPublicPluginMethod().css("color", "red").html("...."); 

다음은 몇 가지 예입니다 (자세한 내용은이 바이올린 확인 ).

// initialize plugin on elements, e.g.:
$("#shape1").myPlugin({shape: 'square', color: 'blue', borderColor: 'SteelBlue'});
$("#shape2").myPlugin({shape: 'rectangle', color: 'red', borderColor: '#ff4d4d'});
$("#shape3").myPlugin({shape: 'circle', color: 'green', borderColor: 'LimeGreen'});

// calling plugin methods to read element specific plugin settings:
console.log($("#shape1").data('myPlugin').inspectSettings());    
console.log($("#shape2").data('myPlugin').inspectSettings());    
console.log($("#shape3").data('myPlugin').inspectSettings());      

// calling plugin methods to modify elements, e.g.:
// (OMG! And they are chainable too!) 
$("#shape1").data('myPlugin').change("circle", "green").fadeOut(2000).fadeIn(2000);      
$("#shape1").data('myPlugin').setBorder('LimeGreen', '30px');

$("#shape2").data('myPlugin').change("rectangle", "red"); 
$("#shape2").data('myPlugin').setBorder('#ff4d4d', '40px').css({
  'width': '350px',
  'font-size': '2em' 
}).slideUp(2000).slideDown(2000);              

$("#shape3").data('myPlugin').change("square", "blue").fadeOut(2000).fadeIn(2000);   
$("#shape3").data('myPlugin').setBorder('SteelBlue', '30px');

// etc. ...     

0

이것은 실제로 "좋은"방식으로 작동하도록 만들 수 있습니다 defineProperty. 여기서 "nice"은 ()플러그인 네임 스페이스를 얻는 데 사용하지 않고 문자열로 함수 이름을 전달 하지 않아도된다는 의미 입니다.

호환성 nit : defineProperty IE8 이하와 같은 고대 브라우저에서는 작동하지 않습니다. 주의 사항 : $.fn.color.blue.apply(foo, args) 작동하지 않습니다 foo.color.blue.apply(foo, args). 을 사용해야 합니다.

function $_color(color)
{
    return this.css('color', color);
}

function $_color_blue()
{
    return this.css('color', 'blue');
}

Object.defineProperty($.fn, 'color',
{
    enumerable: true,
    get: function()
    {
        var self = this;

        var ret = function() { return $_color.apply(self, arguments); }
        ret.blue = function() { return $_color_blue.apply(self, arguments); }

        return ret;
    }
});

$('#foo').color('#f00');
$('#bar').color.blue();

JSFiddle 링크


0

jquery 표준에 따르면 다음과 같이 플러그인을 만들 수 있습니다.

(function($) {

    //methods starts here....
    var methods = {
        init : function(method,options) {
             this.loadKeywords.settings = $.extend({}, this.loadKeywords.defaults, options);
             methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
             $loadkeywordbase=$(this);
        },
        show : function() {
            //your code here.................
        },
        getData : function() {
           //your code here.................
        }

    } // do not put semi colon here otherwise it will not work in ie7
    //end of methods

    //main plugin function starts here...
    $.fn.loadKeywords = function(options,method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(
                    arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not ecw-Keywords');
        }
    };
    $.fn.loadKeywords.defaults = {
            keyName:     'Messages',
            Options:     '1',
            callback: '',
    };
    $.fn.loadKeywords.settings = {};
    //end of plugin keyword function.

})(jQuery);

이 플러그인을 호출하는 방법?

1.$('your element').loadKeywords('show',{'callback':callbackdata,'keyName':'myKey'}); // show() will be called

참조 : 링크


0

나는 이것이 당신을 도울 것이라고 생각합니다 ...

(function ( $ ) {
  
    $.fn.highlight = function( options ) {
  
        // This is the easiest way to have default options.
        var settings = $.extend({
            // These are the defaults.
            color: "#000",
            backgroundColor: "yellow"
        }, options );
  
        // Highlight the collection based on the settings variable.
        return this.css({
            color: settings.color,
            backgroundColor: settings.backgroundColor
        });
  
    };
  
}( jQuery ));

위의 예제에서 간단한 jquery highlight 플러그인을 만들었습니다 . 기본에서 고급으로 자신의 jQuery 플러그인을 만드는 방법에 대해 논의한 기사를 공유했습니다 . 나는 당신이 그것을 체크 아웃해야한다고 생각합니다 ... http://mycodingtricks.com/jquery/how-to-create-your-own-jquery-plugin/


0

다음은 디버깅 목적으로 경고 방법이있는 작은 플러그인입니다. 이 코드를 jquery.debug.js 파일에 보관하십시오 : JS :

jQuery.fn.warning = function() {
   return this.each(function() {
      alert('Tag Name:"' + $(this).prop("tagName") + '".');
   });
};

HTML :

<html>
   <head>
      <title>The jQuery Example</title>

      <script type = "text/javascript" 
         src = "http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

      <script src = "jquery.debug.js" type = "text/javascript"></script>

      <script type = "text/javascript" language = "javascript">
         $(document).ready(function() {
            $("div").warning();
            $("p").warning();
         });
      </script> 
   </head>

   <body>
      <p>This is paragraph</p>
      <div>This is division</div>
   </body>

</html>

0

내가하는 방법은 다음과 같습니다.

(function ( $ ) {

$.fn.gridview = function( options ) {

    ..........
    ..........


    var factory = new htmlFactory();
    factory.header(...);

    ........

};

}( jQuery ));


var htmlFactory = function(){

    //header
     this.header = function(object){
       console.log(object);
  }
 }

-2

당신이 한 일은 기본적으로 jQuery.fn.messagePlugin 객체를 확장하는 것입니다. 를 새로운 메소드로 하는 것입니다. 유용하지만 귀하의 경우에는 그렇지 않습니다.

이 기술을 사용하고 있습니다

function methodA(args){ this // refers to object... }
function saySomething(message){ this.html(message);  to first function }

jQuery.fn.messagePlugin = function(opts) {
  if(opts=='methodA') methodA.call(this);
  if(opts=='saySomething') saySomething.call(this, arguments[0]); // arguments is an array of passed parameters
  return this.each(function(){
    alert(this);
  });

};

그러나 원하는 것을 성취 할 수 있습니다. $ ( "# mydiv"). messagePlugin (). saySomething ( "hello"); 내 친구 그는 lugins에 대한 글을 쓰기 시작했으며 여기에서 기능의 체인으로 확장하는 방법은 블로그 링크입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.