Bagaimana cara membuat plugin jQuery dengan metode?

191

Saya mencoba menulis plugin jQuery yang akan menyediakan fungsi / metode tambahan untuk objek yang memanggilnya. Semua tutorial yang saya baca online (telah menjelajah selama 2 jam terakhir) termasuk, paling banyak, cara menambahkan opsi, tetapi bukan fungsi tambahan.

Inilah yang ingin saya lakukan:

// memformat div untuk menjadi wadah pesan dengan memanggil plugin untuk div itu

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

atau sesuatu di sepanjang garis itu. Inilah intinya: Saya memanggil plugin, lalu saya memanggil fungsi yang terkait dengan plugin itu. Sepertinya saya tidak dapat menemukan cara untuk melakukan ini, dan saya telah melihat banyak plugin melakukannya sebelumnya.

Inilah yang saya miliki sejauh ini untuk plugin:

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);
  }
};

Bagaimana saya bisa mencapai sesuatu seperti itu?

Terima kasih!


Pembaruan 18 Nov 2013: Saya telah mengubah jawaban yang benar untuk komentar dan upvotes Hari berikut ini.

Yuval Karmi
sumber

Jawaban:

310

Menurut halaman Authoring Plugin jQuery ( http://docs.jquery.com/Plugins/Authoring ), yang terbaik adalah tidak memperkeruh ruang nama jQuery dan jQuery.fn. Mereka menyarankan metode ini:

(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 );

Pada dasarnya Anda menyimpan fungsi Anda dalam array (mencakup fungsi pembungkus) dan memeriksa entri jika parameter yang dilewati adalah string, kembali ke metode default ("init" di sini) jika parameternya adalah objek (atau nol).

Maka Anda dapat memanggil metode seperti itu ...

$('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

Variabel Javascript "argumen" adalah array dari semua argumen yang diteruskan sehingga berfungsi dengan parameter fungsi panjang sewenang-wenang.

Hari Karam Singh
sumber
2
Ini adalah metode yang saya gunakan. Anda juga dapat memanggil metode secara statis melalui $ .fn.tooltip ('methodname', params);
Rake36
1
Arsitektur yang sangat berguna. Saya juga menambahkan baris ini sebelum memanggil metode init:, this.data('tooltip', $.extend(true, {}, $.fn.tooltip.defaults, methodOrOptions));jadi sekarang saya dapat mengakses opsi kapan pun saya inginkan setelah inisialisasi.
ivkremer
16
Untuk setiap orang seperti saya yang pertama kali mengatakan "dari mana variabel argumen berasal" - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… - Saya telah menggunakan JS selamanya dan tidak pernah tahu itu. Anda belajar sesuatu yang baru setiap hari!
streetlogics
2
@ Hei, aku bersamamu untuk yang satu ini. Pendekatan ini tampak hebat, tetapi tidak memberi Anda akses ke pengaturan global Anda dari mana pun selain init.
Stephen Collins
4
Ada masalah besar dengan teknik ini! Itu tidak membuat instance baru untuk setiap elemen dalam pemilih seperti yang Anda pikir Anda lakukan, melainkan hanya membuat satu instance yang melekat pada pemilih itu sendiri. Lihat jawaban saya untuk solusi.
Kevin Jurkowski
56

Inilah pola yang saya gunakan untuk membuat plugin dengan metode tambahan. Anda akan menggunakannya seperti:

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

atau, untuk memanggil metode secara langsung,

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

Contoh:

;(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);
tvanfosson
sumber
9
pola yang sama seperti jquery-ui, saya tidak suka semua string ajaib tetapi apakah ada cara lain!
redsquare
8
ini sepertinya cara yang tidak standar dalam melakukan sesuatu - adakah yang lebih sederhana dari ini, seperti fungsi chaining? Terima kasih!
Yuval Karmi
2
@yuval - biasanya jQuery plugins mengembalikan jQuery atau nilai, bukan plugin itu sendiri. Itu sebabnya nama metode dilewatkan sebagai argumen ke plugin ketika Anda ingin memanggil plugin. Anda bisa melewati sejumlah argumen, tetapi Anda harus menyesuaikan fungsi dan penguraian argumen. Mungkin terbaik untuk mengaturnya di objek anonim seperti yang Anda tunjukkan.
tvanfosson
1
Apa arti dari ;baris pertama Anda? tolong jelaskan kepada saya :)
GusDeCooL
4
@GusDeCooL hanya memastikan bahwa kita memulai pernyataan baru sehingga definisi fungsi kita tidak diartikan sebagai argumen untuk Javascript yang diformat buruk oleh orang lain (yaitu, paren awal tidak diambil sebagai operator pemanggilan fungsi). Lihat stackoverflow.com/questions/7365172/…
tvanfosson
35

Bagaimana dengan pendekatan ini:

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');

Objek yang dipilih disimpan dalam penutupan messagePlugin, dan fungsi itu mengembalikan objek yang berisi fungsi yang terkait dengan plugin, di setiap fungsi Anda dapat melakukan tindakan yang diinginkan ke objek yang dipilih saat ini.

Anda dapat menguji dan bermain dengan kode di sini .

Sunting: Kode yang diperbarui untuk menjaga kekuatan rantai jQuery.

CMS
sumber
1
Saya mengalami sedikit kesulitan memahami seperti apa ini nantinya. Dengan asumsi saya memiliki kode yang perlu dieksekusi saat pertama kali dijalankan, saya harus menginisialisasi dalam kode saya - sesuatu seperti ini: $ ('p'). MessagePlugin (); kemudian nanti dalam kode saya ingin memanggil fungsi saySomething seperti ini $ ('p'). messagePlugin (). saySomething ('something'); apakah ini tidak akan menginisialisasi ulang plugin dan kemudian memanggil fungsinya? apa yang akan terlihat dengan kandang dan opsi? Terima kasih banyak. -yuval
Yuval Karmi
1
Semacam mematahkan paradigma chainability jQuery, meskipun.
tvanfosson
mungkin ini harus menjadi jawaban terbaik
Dragouf
3
Setiap kali Anda memanggil messagePlugin (), ia akan membuat objek baru dengan dua fungsi itu, bukan?
w00t
4
Masalah utama dengan pendekatan ini adalah bahwa hal itu tidak dapat mempertahankan berikut chainability $('p').messagePlugin()kecuali Anda memanggil salah satu dari dua fungsi yang dikembalikan.
Joshua Bambrick
18

Masalah dengan jawaban yang dipilih saat ini adalah bahwa Anda tidak benar-benar membuat instance baru plugin kustom untuk setiap elemen dalam pemilih seperti yang Anda pikir sedang Anda lakukan ... Anda sebenarnya hanya membuat satu instance dan mengirimkannya pemilih itu sendiri sebagai ruang lingkup.

Lihat biola ini untuk penjelasan lebih dalam.

Sebagai gantinya, Anda harus mengulangi pemilih menggunakan jQuery.each dan membuat instance baru plugin kustom untuk setiap elemen dalam pemilih.

Begini caranya:

(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);

Dan biola yang bekerja .

Anda akan melihat bagaimana di biola pertama, semua div selalu dipindahkan ke kanan dengan jumlah piksel yang persis sama. Itu karena hanya satu objek opsi ada untuk semua elemen dalam pemilih.

Dengan menggunakan teknik yang ditulis di atas, Anda akan melihat bahwa pada biola kedua, setiap div tidak disejajarkan dan dipindahkan secara acak (tidak termasuk div pertama karena randomizer selalu diatur ke 1 pada baris 89). Itu karena kita sekarang benar instantiating contoh plugin kustom baru untuk setiap elemen dalam pemilih. Setiap elemen memiliki objek opsi sendiri dan tidak disimpan di pemilih, tetapi dalam contoh plugin kustom itu sendiri.

Ini berarti Anda akan dapat mengakses metode plugin khusus yang dipakai pada elemen tertentu di DOM dari pemilih jQuery baru dan tidak dipaksa untuk men-cache mereka, karena Anda akan berada di biola pertama.

Sebagai contoh, ini akan mengembalikan array dari semua objek pilihan menggunakan teknik di biola kedua. Itu akan kembali tidak terdefinisi di yang pertama.

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

Ini adalah bagaimana Anda harus mengakses objek pilihan di biola pertama, dan hanya akan mengembalikan satu objek, bukan array dari mereka:

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

Saya sarankan menggunakan teknik di atas, bukan yang dari jawaban yang dipilih saat ini.

Kevin Jurkowski
sumber
Terima kasih, ini banyak membantu saya, terutama memperkenalkan metode .data () kepada saya. Sangat berguna. FWIW Anda juga dapat menyederhanakan beberapa kode Anda dengan menggunakan metode anonim.
dalemac
jQuery chainability tidak bekerja menggunakan metode ini ... $('.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 telah membuat ini jauh lebih mudah dengan diperkenalkannya Pabrik Widget .

Contoh:

$.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 ) {
        // ...
    }

});

Inisialisasi:

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

Metode memanggil:

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

(Ini adalah bagaimana perpustakaan jQuery UI dibangun.)

Yarin
sumber
@ daniel.sedlacek a) "arsitektur yang sangat buruk" - ini adalah arsitektur widget standar jQuery b) "memeriksa integritas pada waktu kompilasi" - JavaScript adalah bahasa yang dinamis c) "TypeScript" - wha?
Yarin
a) itu argumentum ad populum, b) setiap IDE JS lebih baik memiliki pelengkapan kode atau linting, c) google it
daniel.sedlacek
Itu adalah khayalan murni, Tn. Sedlacek.
mystrdat
Per dokumen: Sistem ini disebut Pabrik Widget dan diekspos sebagai jQuery.widget sebagai bagian dari jQuery UI 1.8; namun, ini dapat digunakan secara terpisah dari jQuery UI. Bagaimana $ .widget digunakan tanpa jQuery UI?
Airn5475
13

Pendekatan yang lebih sederhana adalah dengan menggunakan fungsi bersarang. Kemudian Anda bisa memadukannya dengan cara yang berorientasi objek. Contoh:

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;
};

Dan inilah cara menyebutnya:

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

Berhati-hatilah. Anda tidak dapat memanggil fungsi bersarang sampai fungsi itu dibuat. Jadi Anda tidak bisa melakukan ini:

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

Fungsi DoEvenMore bahkan tidak ada karena fungsi DoSomething belum dijalankan yang diperlukan untuk membuat fungsi DoEvenMore. Untuk sebagian besar plugin jQuery, Anda benar-benar hanya akan memiliki satu tingkat fungsi bersarang dan bukan dua tingkat seperti yang saya tunjukkan di sini.
Pastikan bahwa ketika Anda membuat fungsi bersarang Anda mendefinisikan fungsi-fungsi ini di awal fungsi induknya sebelum kode lain dalam fungsi induk dijalankan.

Akhirnya, perhatikan bahwa anggota "ini" disimpan dalam variabel yang disebut "_ini". Untuk fungsi bersarang, Anda harus mengembalikan "_ini" jika Anda memerlukan referensi ke instance di klien panggilan. Anda tidak bisa hanya mengembalikan "ini" dalam fungsi bersarang karena itu akan mengembalikan referensi ke fungsi dan bukan contoh jQuery. Mengembalikan referensi jQuery memungkinkan Anda untuk mengaitkan metode jQuery intrinsik saat kembali.

Polaris431
sumber
2
Ini hebat - saya hanya bertanya-tanya mengapa jQuery tampaknya lebih suka memanggil metode dengan nama seperti pada pola .plugin ('metode')?
w00t
6
Ini tidak bekerja. Jika Anda menjalankan plugin pada dua wadah berbeda, variabel internal akan diganti (yaitu _this)
mbrochh
Gagal: tidak mengizinkan pluginContainer.MyPlugin.DoEvenMore (). DoSomething ();
Paul Swetz
9

Saya mendapatkannya dari jQuery Plugin Boilerplate

Juga dijelaskan di jQuery Plugin Boilerplate, reprise

// 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);
MaxEcho
sumber
Metode Anda memecah rantai jQuery: $('.first-input').data('pluginName').publicMethod('new value').css('color', red);mengembalikan Cannot read property 'css' of undefined jsfiddle.net/h8v1k2pL/1
Alex G
@AlexG memberikan contoh ini, Anda akan menambahkannya return $elementdalam contoh ini Anda akan mengubahnya menjadi plugin.foo_public_method = function() {/* Your Code */ return $element;}@Salim terima kasih telah membantu saya ... github.com/AndreaLombardo/BootSideMenu/pull/34
CrandellWS
6

Terlambat tapi mungkin itu bisa membantu seseorang suatu hari.

Saya berada dalam situasi yang sama seperti, membuat plugin jQuery dengan beberapa metode, dan setelah membaca beberapa artikel dan beberapa ban saya membuat boilerplate plugin jQuery ( https://github.com/acanimal/jQuery-Plugin-Boilerplate ).

Selain itu, saya mengembangkan dengannya sebuah plugin untuk mengelola tag ( https://github.com/acanimal/tagger.js ) dan menulis dua posting blog yang menjelaskan langkah demi langkah pembuatan plugin jQuery ( http: // acuriousanimal. com / blog / 2013/01/15 / hal-i-pelajari-membuat-jquery-plugin-bagian-i / ).

EricSonaron
sumber
mungkin posting terbaik yang pernah saya temui tentang membuat plugin jQuery sebagai pemula - terima kasih;)
Dex Dave
5

Anda dapat melakukan:

(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]();
        }
      }
    });
  };
});

Dengan cara ini objek plugin Anda disimpan sebagai nilai data dalam elemen Anda.

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

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

// call show method
$('#myId').yourPlugin('show');
Mazaher Bazari
sumber
3

Bagaimana dengan menggunakan pemicu? Apakah ada yang tahu ada kelemahan menggunakannya? Manfaatnya adalah bahwa semua variabel internal dapat diakses melalui pemicu, dan kode ini sangat sederhana.

Lihat di jsfiddle .

Contoh penggunaan

<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>

Plugin

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>');
        }

    });

}
István Ujj-Mészáros
sumber
1
lih. komentar Anda. Satu-satunya masalah yang saya lihat di sini adalah penyalahgunaan sistem acara. Tidak lazim menggunakan acara hanya untuk menjalankan fungsi; sepertinya berlebihan dan mungkin mudah rusak. Biasanya, Anda akan menggunakan acara dengan cara menerbitkan-berlangganan, misalnya, fungsi menerbitkan bahwa beberapa kondisi "A" telah terjadi. Entitas lain, yang tertarik pada "A", mendengarkan pesan bahwa "A" telah terjadi, lalu lakukan sesuatu. Anda tampaknya menggunakannya sebagai "perintah" push, tetapi dengan asumsi hanya ada satu pendengar. Anda ingin berhati-hati agar semantik Anda tidak rusak oleh (yang lain) menambahkan pendengar.
tvanfosson
@tvanfosson Terima kasih atas komentar Anda. Saya mengerti bahwa ini bukan teknik yang umum dan dapat menyebabkan masalah jika seseorang secara tidak sengaja menambahkan pendengar acara, tetapi jika dinamai setelah plugin, maka sangat tidak mungkin. Saya tidak tahu tentang masalah yang berkaitan dengan kinerja, tetapi kode itu sendiri tampaknya lebih sederhana bagi saya daripada dengan solusi lain, tetapi saya mungkin kehilangan sesuatu.
István Ujj-Mészáros
3

Di sini saya ingin menyarankan langkah-langkah untuk membuat plugin sederhana dengan argumen.

(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>

Di sini, kami telah menambahkan objek default yang dipanggil paramsdan menetapkan nilai default opsi menggunakan extendfungsi. Oleh karena itu, Jika kita melewati argumen kosong maka itu akan menetapkan nilai default sebagai gantinya sebaliknya akan ditetapkan.

Baca selengkapnya: Cara Membuat plugin JQuery

Gopal Joshi
sumber
Halo Gopal Joshi, Tolong beri kreasi plugin jquery level selanjutnya. kami harapkan dari jawaban Anda yang diperlukan.
Sakthi Karthik
Hello @SakthiKarthik, Off cource Saya akan segera mempublikasikan tutorial di blog saya
Gopal Joshi
1
Hai @ SakthiKarthik, Anda dapat merujuk artikel baru di plugin jquery level berikutnya di sini sgeek.org/…
Gopal Joshi
2

Coba yang ini:

$.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
Serkan KONAKCI
sumber
1

Ini adalah versi sederhana dari ini. Mirip dengan yang diposting sebelumnya, Anda akan memanggil seperti:

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

-atau mengakses instance secara langsung @ 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);
jtrumbull
sumber
1

Berikut plugin-struktur memanfaatkan jQuery- data()-Metode untuk menyediakan antarmuka publik untuk intern plugin-metode / -settings (sambil menjaga jQuery-chainability):

(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));

Sekarang Anda dapat memanggil metode plugin internal untuk mengakses atau mengubah data plugin atau elemen yang relevan menggunakan sintaks ini:

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

Selama Anda mengembalikan elemen saat ini (ini) dari dalam implementasi myPublicPluginMethod()jQuery-chainability Anda akan dipertahankan - sehingga hal-hal berikut berfungsi:

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

Berikut adalah beberapa contoh (untuk detail checkout biola ini ):

// 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. ...     
Mayinx
sumber
0

Ini sebenarnya bisa dibuat untuk bekerja dengan cara yang "baik" menggunakan defineProperty. Di mana "nice" berarti tanpa harus menggunakan ()untuk mendapatkan plugin namespace atau harus melewati fungsi name by string.

Nit kompatibilitas: defineProperty tidak berfungsi di browser kuno seperti IE8 dan di bawah. Peringatan: $.fn.color.blue.apply(foo, args) tidak akan berfungsi, Anda harus menggunakan 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();

Tautan JSFiddle

kralyk
sumber
0

Menurut standar jquery Anda dapat membuat plugin sebagai berikut:

(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);

Bagaimana cara memanggil plugin ini?

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

Referensi: tautan

Mahesh
sumber
0

Saya pikir ini dapat membantu Anda ...

(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 ));

Dalam contoh di atas saya telah membuat plugin sorot jquery sederhana. Saya telah berbagi artikel yang telah saya bahas tentang Cara Membuat Plugin jQuery Anda Sendiri dari Basic hingga Advance. Saya pikir Anda harus memeriksanya ... http://mycodingtricks.com/jquery/how-to-create-your-own-jquery-plugin/

Shubham Kumar
sumber
0

Berikut ini adalah plug-in kecil yang memiliki metode peringatan untuk tujuan debugging. Simpan kode ini di file 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>
jayaweb
sumber
0

Inilah cara saya melakukannya:

(function ( $ ) {

$.fn.gridview = function( options ) {

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


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

    ........

};

}( jQuery ));


var htmlFactory = function(){

    //header
     this.header = function(object){
       console.log(object);
  }
 }
Mina Gabriel
sumber
-2

Apa yang Anda lakukan pada dasarnya meluas objek jQuery.fn.messagePlugin dengan metode baru. Yang berguna tetapi tidak dalam kasus Anda.

Yang harus Anda lakukan adalah menggunakan teknik ini

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);
  });

};

Tetapi Anda dapat mencapai apa yang Anda inginkan. Maksud saya ada cara untuk melakukan $ ("# mydiv"). MessagePlugin (). SaySomething ("hello"); Teman saya dia mulai menulis tentang lugins dan bagaimana memperluasnya dengan rangkaian fungsi Anda di sini adalah tautan ke blog-nya

James
sumber