2013-07-17 5 views
6

Es genügt zu sagen, ich möchte mein Plugin schreiben ein wenig zu schreiben, und entschied, ich möchte in der Lage sein, sie "namespace". Bisher ist das Umschreiben der $.method-Einsen in $.namespace.method einfach.Wie man jQuery-Element-Methoden mit NameSpace erstellt

Das Problem, das ich habe, macht Element Methoden wie $('element').method(), aber einen Namespace zu verwenden; zum Beispiel $('element').namespace.method(). Ich habe ein paar Workarounds versucht und kann $.fn.namespace.method erstellen, aber wenn ich this von innerhalb dieser Methode aufrufen, bekomme ich nur $.fn.namespace und nicht die 'element', die ich gerne bekommen würde.

Beispiel: Wenn ich $('body').namespace.test() nennen, dann innerhalb Methode test, möchte ich this das Element <body></body>

Jede Hilfe herauszufinden sein, wie dies sehr geschätzt abziehen. Vermutlich nur Dinge wie gewohnt überdenken.

versucht derzeit mögliche Abhilfen für so etwas wie $('body').namespace().method() sie bisher nicht so gut funktioniert ...: P

+0

+1 - Ich glaube nicht, dass dies in JavaScript möglich ist. Sie sollten nur Ihren Methodennamen voranstellen (z. B. 'namespaceTest'). Wenn ein echter Namespace für Sie so wichtig ist, dann können Sie den Prototyp von jQuery leider nicht verwenden. –

+0

Ich vermisse vielleicht Ihren Punkt, aber suchen Sie nur nach '$ .fn.myMethod (/ * Funktionscode * /);' was Sie dann wie '$ (" div ") aufrufen. MyMethod()'? – Archer

+1

@JosephSilber Es ist JavaScript! Ich bin sicher, dass es einen Weg gibt! LoL, schließlich ist das die "freieste" Sprache da draußen! – SpYk3HH

Antwort

3

Wenn Sie mit IE8 kompatibel nicht sein müssen, Sie Object.defineProperty verwenden.

Arbeitsbeispiel:

Object.defineProperty($.fn, 'namespace', { 
    get: function(){ 
    var t = this; 
    return { 
     lowercasehtml: function(){ 
     return t.html(function(_,h){ return h.toLowerCase() }); 
     } 
    } 
    } 
}); 

$('#a').namespace.lowercasehtml(); // changes the html of #a to lowercase (yes, it's stupid, I know) 

Demonstration

Aber ich bin nicht überzeugt, dass es eine gute Idee, wie dieses Namespace. Ich würde einfach

$.fn.namespace_lowercasehtml = function() ... 

definiert haben, das ist, was ich für meine Anwendung spezifische Erweiterungen zu jQuery persönlich tun.

+0

netter Vorschlag, ich werde es gleich nach dem Mittagessen versuchen, irgendwelche Gedanken auf IE8 arbeiten herum? – SpYk3HH

+0

Um ehrlich zu sein, denke ich, dass mein zweiter Vorschlag, wenn auch nicht schick, der beste ist. –

2

Während ich es nicht empfehlen, können Sie ein neues Objekt für jeden Aufruf zu namespace() erzeugen:

(function($){ 

    var plugin = { 
     test: function(){ 
      console.log(this); 
     } 
    }; 

    var methods = Object.keys(plugin); 

    $.fn.namespace = function(){ 

     var self = this, 
      localMethods = {}; 

     $.each(methods, function() { 
      localMethods[ this ] = plugin[ this ].bind(self); 
     }); 

     return localMethods; 
    }; 

}(jQuery)); 

Hier ist die Geige: http://jsfiddle.net/WaXzL/


Sie können entweder polyfill Object.keys for older browsers, oder einfach nur Erstellen Sie das Array methods manuell.

Das gleiche gilt für bind: entweder polyfill es, oder call es manuell.

Hier ist eine Version, die in älteren Browsern funktionieren würde:

(function($){ 

    var plugin = { 
     test: function(){ 
      console.log(this); 
     } 
    }; 

    var methods = []; 

    for (var i in plugin) { 
     if (plugin.hasOwnProperty(i)) { 
      methods.push(i); 
     } 
    } 

    $.fn.namespace = function(){ 

     var self = this, 
      localMethods = {}; 

     $.each(methods, function (i, method) { 
      localMethods[ method ] = function() { 
       plugin[ method ].call(self); 
      }; 
     }); 

     return localMethods; 
    }; 

}(jQuery)); 

Und hier ist die Geige: http://jsfiddle.net/WaXzL/1/

+0

Danke für Ihren Vorschlag. Ich habe Unterstützung für das Übergeben von Argumenten an jede lokale Methode hinzugefügt: http://jsfiddle.net/WaXzL/2/ –

2

Wie wäre es anstatt das zu tun:

$('element').namespace.method() 

Sie es und tun vereinfachen

$('element').namespace('method') 

stattdessen?Das ist viel einfacher:

(function($){ 
    var methods = { 
     test: function(a, b){ 
      console.log(this, a, b); 
     } 
    }; 

    $.fn.namespace = function(method){ 
     var params = Array.prototype.slice.call(arguments, 1); 
     return methods[method].apply(this, params); 
    }; 
}(jQuery)); 

Dann würden Sie so etwas wie: $('body').namespace('test', 1, 2);

+0

, weil meine IntelliSense in meiner IDE '$ ('ele') liest. Namespace.method()' aber es hat gewonnen ' t lese einen Methodennamen, der als String param übergeben wurde – SpYk3HH

+3

@ SpYk3HH: Ich habe versucht, es einfach zu halten. Ich verwende keine "ausgefallene" IDE. –

2

Eine bessere Lösung ist nur eine Hauptmethode, haben und die Methodennamen als String übergeben:

(function($){ 

    var plugin = { 
     test: function(){ 
      console.log(this); 
     }, 
     otherTest: function(){ 
      console.log(this); 
     } 
    }; 

    $.fn.namespace = function (method){ 
     var args = Array.prototype.slice.call(arguments, 1); 
     return plugin[ method ].call(this, args); 
    }; 

}(jQuery)); 

Hier ist die Geige: http://jsfiddle.net/yYNDH/

+0

Ist das nicht schon eine andere Antwort (von Rocket)? –

+1

@dystroy - Ja. Ich war zu JSFiddle hinübergegangen, um die Fidel zu kreieren, bevor ich auflegte, und als ich zurückkam, war mir nicht klar, dass er es schon gepostet hatte. –

Verwandte Themen