2009-06-25 8 views
15

Il mio obiettivo è essere in grado di chiamare le funzioni presenti nel mio plugin JQuery.Come chiamare le funzioni che sono nidificate all'interno di un plugin JQuery?

Qual è la sintassi corretta?

Ad esempio, questa non funziona:

<a href="#" id="click_me">Click Me</a> 

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
<script> 
(function($) { 
    $.fn.foo = function(options) { 
     do_stuff = function(){ 
      console.log("hello world!"); // works 
      do_other_stuff = function(){ 
      alert("who are you?"); 
      } 
     } // function 
    } // function 
})(jQuery); 

$("body").foo(); 

$("#click_me").click(function(){ 
$.fn.foo.do_stuff.do_other_stuff(); // doesn't work 
}); 

</script> 

risposta

35

quando si assegnano le funzioni alle variabili senza la parola chiave var essi o sovrascrivere la variabile locale di quel nome o sono aggiunti al namespace globale. (quindi il tuo do_stuff è una funzione globale, che non è ciò che desideri)

un modo per fare ciò che vuoi è dare esplicitamente dove vuoi che risieda la tua funzione.

(function($) { 
    $.fn.foo = function(options) { 
     // whatever $().foo() should do 
    }; 

    $.fn.foo.do_stuff = function() { 
     console.log("hello world!"); 
    }; 

    $.fn.foo.do_stuff.do_other_stuff = function(){ 
     alert("who are you?"); 
    }; 
})(jQuery); 

Edit:

Questo funziona perché tutte le funzioni in JavaScript sono oggetti, il che significa che è possibile assegnare valori a qualsiasi proprietà arbitraria.

Se si desidera accedere alle variabili delle altre funzioni è possibile spostare le definizioni all'interno di quelli di altri come:

$.fn.foo.do_stuff = function() { 
    console.log("hello world!"); 
    $.fn.foo.do_stuff.do_other_stuff = function(){ 
     alert("who are you?"); 
    }; 
}; 

ma questo significherà la funzione è definita solo una volta che si esegue l'altra funzione, e che ogni volta che si esegue la funzione sovrascriverà l'ultima definizione.

Forse una soluzione più ideale sarebbe avere ogni funzione restituisce un oggetto contenente la funzione nidificata modo:

(function($) { 
    $.fn.foo = function(options) { 
     // whatever $().foo() should do 

     var do_stuff = function(do_stuff_args) { 
      console.log("hello world!"); 
      // do stuff with options and do_stuff_args 

      var do_other_stuff = function(other_args) { 
       alert("who are you?"); 
       // here you have access to options, do_stuff_args, and other_args 
      }; 

      return { 
       do_other_stuff: do_other_stuff 
      }; 
     }; 

     return { 
      do_stuff: do_stuff 
     } 
    }; 
})(jQuery); 

e chiamare utilizzando

foo().do_stuff(some_options).do_other_stuff(other_options); 

o

var a = foo(stuff).do_stuff(some_options); 
a.do_other_stuff(foo); 
a.do_other_stuff(bar); 
+0

Non capisco davvero perché funzioni. Pensavo che $ .fn.foo potesse essere una funzione o un oggetto con la proprietà do_stuff, ma nel tuo esempio è entrambi. Questo è possibile in JavaScript? Potresti darmi un puntatore per leggere questa funzione? O ho qualcosa di sbagliato qui? –

+0

Grazie per l'esempio, funziona. Il mio plugin è già pronto. Il tuo esempio non corrisponde alla struttura del mio plugin. Nel mio plugin, "do_stuff" è dentro "foo" e "do_other_stuff" è dentro "do_stuff". Come posso accedere a "fare altre cose" usando quella struttura annidata? Oppure, come posso usare il tuo esempio, ma permetti a do_stuff di accedere alle variabili da foo (e lasciare che do_other_stuff acceda alle variabili da do_stuff)? – edt

+2

Grazie a Cobbal, ho capito come usare il tuo esempio con la mia struttura di funzioni. Funziona alla grande! Ho appena dovuto usare $ .fn.foo. [Nome_funzione] per tutte le funzioni annidate, indipendentemente dal loro livello. – edt

Problemi correlati