Beste Möglichkeit, ein jQuery-Plugin zu erweitern

77

Ich bin ein ziemlich neuer jQuery-Benutzer, der ein vorhandenes jQuery-Plugin erweitern möchte, das ungefähr 75% meiner Anforderungen erfüllt. Ich habe versucht, meine Hausaufgaben zu machen. Ich habe die folgenden Fragen zum Stackoverflow geprüft:

Ich habe gelesen oben auf dem verlängern Verfahren. All diese Hausaufgaben haben mich jedoch verwirrt. Ich arbeite mit dem Vollkalender- Plugin und muss einige Verhaltensweisen ändern sowie neue Ereignis-Hooks hinzufügen. Muss ich das im Plugin-Verschluss selbst tun? Vermisse ich etwas Offensichtliches?

Idealerweise können wir unseren Code vom Plugin-Code trennen, um ein mögliches Upgrade zu ermöglichen. Jede Hilfe wäre sehr dankbar, insbesondere Hinweise darauf, wo mir Informationen oder Meinungen fehlen, ob die Lösungen, die bereits in anderen Fragen zum Stapelüberlauf vorgestellt wurden, sinnvoll sind. Für mich widersprechen sie sich und ich bin immer noch verwirrt.

justkt
quelle
justkt, Können Sie einen Beispielcode veröffentlichen, wie Sie das Vollkalender-Plugin erweitert haben? Ich versuche gerade, das Gleiche zu tun, bin aber ratlos und kann keine der Funktionen aufrufen, die ich angeblich hinzugefügt habe.
Matt McCormick
@MattMcCormick - haben Sie die unten aufgeführte akzeptierte Antwort ausprobiert?
Justkt
Ah, ich habe .prototype aufgenommen. Das habe ich nicht gebraucht. Jetzt habe ich nur noch $ .extend (true, $ .fullCalendar, extensionMethods); und es funktioniert! Idealerweise möchte ich das Ereignisobjekt erweitern, aber das hat keinen Namespace, sodass ich nicht sehe, wie das möglich wäre. Dies funktioniert jedoch vorerst.
Matt McCormick
2
Siehe msdn.microsoft.com/en-us/library/hh404085.aspx (Kapitel Vererbung)
Katrin

Antworten:

85

Ich hatte gerade das gleiche Problem beim Versuch, jquery UI-Plugins zu erweitern, und hier ist die Lösung, die ich gefunden habe (gefunden über jquery.ui.widget.js):

(Funktion ($) {
/ **
 * Namespace: Der Namespace, unter dem sich das Plugin befindet
 * pluginName: Der Name des Plugins
 * /
    var extensionMethods = {
        / *
         * Ruft die ID des Elements ab
         * Dies ist ein Kontext innerhalb des vorhandenen Plugins
         * /
        showId: function () {
            return this.element [0] .id;
        }}
    };

    $ .extend (true, $ [Namespace] [pluginName] .prototype, extensionMethods);


}) (jQuery);

Ich hoffe, dies hilft. Bitte fragen Sie, wenn Sie Fragen haben.

Jared Scott
quelle
2
Wenn ich also die automatische Vervollständigung der jQuery-Benutzeroberfläche erweitern Namespacemöchte, wäre dies "ui" und pluginName"autocomplete".
Matt Huggins
1
Ich glaube, ich habe meine eigene Frage beantwortet. Ich habe in der Autocomplete-Quelle gefunden, wo es aufruft jQuery.widget("ui.autocomplete", ...), und in der Widget-Quelle, wo es am "." Teilt, wobei der Namespace Index 0 und pluginName Index 1 ist. Mit anderen Worten, es sieht so aus, als hätte ich recht. :)
Matt Huggins
4
@Jared - Am Ende habe ich Ihren Rat hier befolgt, um die automatische Vervollständigung der jQuery-Benutzeroberfläche zu erweitern. Ich beschreibe meine Ziele hier: matthuggins.com/articles/… und ich habe den vollständigen Code hier: github.com/mhuggins/jquery-ui-autocomplete-hints . Wenn Sie Verbesserungsvorschläge haben, würde ich sie gerne hören!
Matt Huggins
4
Wie finde ich Namespace und PluginName?
Pablo SG Pacheco
17

Ich hatte das gleiche Problem und kam hierher, dann inspirierte mich Jared Scotts Antwort.

(function($) {

    var fullCalendarOrg = $.fn.fullCalendar;

    $.fn.fullCalendar = function(options) {
        if(typeof options === "object") {
            options = $.extend(true, options, {
                // locale
                isRTL: false,
                firstDay: 1,
                // some more options
            });
        }

        var args = Array.prototype.slice.call(arguments,0);
        return fullCalendarOrg.apply(this, args);
    }

})(jQuery);
Nepjua
quelle
3

Ich habe festgestellt, dass bei vielen Plugins die Methoden geschützt / privat sind (dh im Closures-Bereich). Wenn Sie die Funktionalität der Methoden / Funktionen ändern müssen, haben Sie kein Glück, es sei denn, Sie sind bereit, dies zu tun. Wenn Sie keine dieser Methoden / Funktionen ändern müssen, können Sie sie verwenden$.extend($.fn.pluginName, {/*your methods/properties*/};

Eine andere Sache, die ich vorher getan habe, ist einfach das Plugin als eine Eigenschaft meines Plugins zu verwenden, anstatt zu versuchen, es zu erweitern.

Worauf es wirklich ankommt, ist, wie das Plugin, das Sie erweitern möchten, codiert ist.

prodigitalson
quelle
In der Haupterweiterung ist alles, was ich tun möchte, aber in einigen Fällen geht es darum, Ereignishandler für DOM-Elemente hinzuzufügen, die im Plugin erstellt wurden. In anderen Fällen muss ich das Verhalten innerhalb vorhandener Methoden überschreiben. Je mehr ich lese, desto weniger sehe ich einen sauberen Weg, dies zu tun. Irgendwelche anderen Gedanken?
Justkt
Nun, wenn diese Methoden in der öffentlichen API enthalten sind (was sie nicht zu sein scheinen), können Sie die oben erwähnte Methode verwenden, um die Funktionsdefinition zu ersetzen. Ansonsten gibt es keinen sauberen Weg. Sie müssen es nur für Ihre Zwecke gabeln und weghacken.
Prodigitalson
2
@prodigitalson public * API;)
Niks
2
$.fn.APluginName=function(param1,param2)
{
  return this.each(function()
    {
      //access element like 
      // var elm=$(this);
    });
}

// sample plugin
$.fn.DoubleWidth=function()
  {
    return this.each(function()
      {
        var _doublWidth=$(this).width() * 2;
        $(this).width(_doubleWidth);
      });
  }

// //

<div style="width:200px" id='div!'>some text</div>

// mit benutzerdefiniertem Plugin

$('#div1').DoubleWidth();

/// über dem geschriebenen Typ von Utils arbeiten normalerweise mit dom-Elementen //////////////// benutzerdefinierten Utils

(function($){
  var _someLocalVar;
  $.Afunction=function(param1,param2) {
    // do something
  }
})(jquery);

// Zugriff über util als

$.Afunction();

// Diese Art von Utils erweitert normalerweise Javascript

Praveen Prasad
quelle
1
Das ist nicht das, was er fragt - er fragt, wie ein bereits vorhandenes Plugin am besten so erweitert werden kann, dass das zugrunde liegende Plugin aktualisiert werden kann, das als Basis verwendet wird, während die gewünschte Funktionalität hinzugefügt wird.
Prodigitalson
1

Mein Ansatz beim Umschreiben von jQuery-Plugins bestand darin, Methoden und Variablen, auf die zugegriffen werden muss, in den Optionsblock zu verschieben und die Option "Erweitern" aufzurufen.

// in the plugin js file
$.jCal = function (target, opt) {
    opt = $.extend({
       someFunctionWeWantToExpose: function() {
           // 'this' refers to 'opt', which is where are our required members can be found
       }
    }

    // do all sorts of things here to initialize

    return opt; // the plugin initialisation returns an extended options object
}


////// elsewhere /////

var calendar = $("#cal1").jCal();
calendar.someFunctionWeWantToExpose();
hvdd
quelle
1

Ein Beispiel ähnlich der Antwort von Jared Scott, aber das Erstellen einer Kopie des ursprünglichen Objektprototyps bietet die Möglichkeit, die übergeordnete Methode aufzurufen:

(function($) {

    var original = $.extend(true, {}, $.cg.combogrid.prototype);

    var extension = {
        _renderHeader: function(ul, colModel) {
            original._renderHeader.apply(this, arguments);

            //do something else here...
        }
    };

    $.extend(true, $.cg.combogrid.prototype, extension);

})(jQuery);
marcini
quelle